Skip to content

D optimization techniques

lomereiter edited this page Dec 16, 2012 · 5 revisions

Uninitialized arrays

By default, D initializes elements of allocated array. In a lot of cases, this is not needed. For instance, if the chunk of memory is allocated just to be filled from some Stream. In order to avoid this extra overhead, use std.array.uninitializedArray function.

Uninitialized variables

The same goes for variables. In this case, you can just use = void in variable declaration.

Final methods and classes

By default, all methods are virtual. You can mark them as final to avoid extra indirection. Also, the whole class can be marked as final.

Use structs instead of classes wherever possible

Structs are more lightweight. Of course you lose inheritance and interfaces in this case, but there're mixins and compile-time polymorphism, therefore flexible design is still possible.

Allocate classes on stack if they're needed in current scope only.

If a class instance is needed only in the current scope, it can be allocated on stack to avoid new overhead. The preferred way to do it is to use std.typecons.scoped function.

Fast output

Unfortunately, write/writef/etc. are slow. Use good old printf instead. To output not zero-terminated D string, use "%.*s" format string: printf("%.*s", str.length, str.ptr);

However, printf is also relatively slow because it parses format string each time you call it. Therefore, it's better to avoid it if you want maximum performance.

The best approach is to use fwrite() only, preparing the string in memory. In case your strings are short, you can use alloca to build them on stack, and then write to a stream. That allows to avoid any memory allocations.

BioD has bio.core.utils.format module, which wraps all of this into easy-to-use interface.

std.traits.hasIndirections

Useful for making library with C-like interface, when you need to manually allocate/deallocate memory. Allows to eliminate unnecessary GC.addRange/GC.removeRange calls. Avoiding them manually is dangerous due to possible future changes which might break your code, while static if + hasIndirections makes your code safe.

(At the moment, shared libraries are not possible due to lack of support in druntime.)