This post was inspired by my recent work optimizing D's garbage collector and the Port A Benchmark thread.

The current implementation of druntime flags **ALL** classes as having finalizers when allocated via the new operator, even if they don't. The GC then calls an empty finalizer pointed to by class's vtable. In certain GC benchmarks, calling all these empty finalizers actually adds up to a substantial (~15-20%) performance penalty.

For example, the tree benchmark provided by Bearophile back when I was working on GC optimizations (available at https://github.com/dsimcha/druntime/blob/master/gcBench/tree1.d) runs in about 44-45 seconds on my machine using stock DMD 2.053. It creates tons of tiny class objects with no finalizers. When I temporarily disable calling finalizers in the GC code, the runtime for this benchmark is cut to 36-37 seconds. If this isn't low-hanging fruit, I don't know what is.

What we need is to include a hasFinalizer field in ClassInfo that is true iff a class or any of its ancestors has a non-empty finalizer. Then, the finalize flag in the GC can be set on allocating a class using the new operator only if this flag is true. This would save the time spent calling empty finalizers in places where tons of small, finalizer-free classes are allocated, and probably result in a decent speedup.

I've filed an enhancement request to get a hasFinalizer field in Classinfo. (http://d.puremagic.com/issues/show_bug.cgi?id=6103) I am not familiar enough with the DMD codebase to do this myself, but I imagine it's a pretty simple enhancement for someone who is. If someone else takes care of the compiler, I'll take care of the corresponding druntime changes.

Reply via email to