TLDR; a non-optimized fqn using core.reflect is roughly 4 times faster than the phobos version.
I have had issues with the fullyQualifiedName template in std.phobos for a while.
So I have implemented a version of it for core.reflect.utils
which uses the core.reflect transitive parent reflection.
For those how are not interested in the code. First comes the little performance comparison.
First with an ldc optimized -O3 build of the compiler, which is what you should use in a commercial setting:
Benchmark #1: generated/linux/release/64/dmd -version=core_reflect -c fqn_reflect.d
Time (mean ± σ): 19.6 ms ± 2.9 ms [User: 14.5 ms, System: 5.3 ms]
Range (min … max): 12.6 ms … 27.3 ms 142 runs
Benchmark #2: generated/linux/release/64/dmd -version=phobos_fqn -c fqn_reflect.d
Time (mean ± σ): 73.9 ms ± 2.5 ms [User: 57.1 ms, System: 16.9 ms]
Range (min … max): 64.9 ms … 80.7 ms 38 runs
Summary
'generated/linux/release/64/dmd -version=core_reflect -c fqn_reflect.d' ran
3.78 ± 0.57 times faster than 'generated/linux/release/64/dmd -version=phobos_fqn -c fqn_reflect.d'
And now with a dmd debug build of the compiler that I use for faster iteration when working on compiler features.
Benchmark #1: generated/linux/release/64/dmd -version=core_reflect -c fqn_reflect.d
Time (mean ± σ): 30.3 ms ± 2.4 ms [User: 25.5 ms, System: 4.7 ms]
Range (min … max): 22.7 ms … 40.9 ms 98 runs
Benchmark #2: generated/linux/release/64/dmd -version=phobos_fqn -c fqn_reflect.d
Time (mean ± σ): 120.2 ms ± 2.4 ms [User: 104.9 ms, System: 15.1 ms]
Range (min … max): 116.9 ms … 125.9 ms 24 runs
Summary
'generated/linux/release/64/dmd -version=core_reflect -c fqn_reflect.d' ran
3.97 ± 0.32 times faster than 'generated/linux/release/64/dmd -version=phobos_fqn -c fqn_reflect.d'
Now comes the source of fqn_reflect.d
unedited this time to avoid typos.
module reflect.showcases.nicer.java.like.package_.structure.fqn_reflect;
struct U
{
struct V
{
struct W{
class C
{ int x; }
}
}
}
version (core_reflect)
{
import core.reflect.utils;
static assert(fqn!(U.V.W.C) == "reflect.showcases.nicer.java.like.package_.structure.fqn_reflect.U.V.W.C");
}
version (phobos_fqn)
{
import std.traits;
static assert(fullyQualifiedName!(U.V.W.C) == "reflect.showcases.nicer.java.like.package_.structure.fqn_reflect.U.V.W.C");
}
What about memory usage?
I am glad you asked. Memory usage is around 3 times lower.
Cheers,
Stefan