Compiler performance with my ridiculous Binderoo code
Chris Wright via Digitalmars-d
digitalmars-d at puremagic.com
Sun Dec 11 14:48:56 PST 2016
On Sun, 11 Dec 2016 18:08:04 +0000, safety0ff wrote:
> However, I understand the quadratic nature of comparing:
> AliasSeq!(AliasSeq!(AliasSeq!(...)))
> to:
> AliasSeq!(AliasSeq!(...))
That's one option. Here's another:
Template instantiations are interned as they are constructed (or at least
should be). You must construct their arguments before you instantiate the
template. Therefore you can do a reference equality check instead of
checking the values of the parameters.
Specifically, we have:
AliasSeq!(AliasSeq!(1, 2), 3)
To construct this, the compiler first constructs AliasSeq!(1, 2). It's
already been instantiated, so instead of creating it anew, it grabs a
pointer to the existing instantiation -- we'll call it 0xC0FE.
Now it looks if AliasSeq!(0xC0FE, 3) has already been instantiated. It
hasn't, so we instantiate it and add it to the cache.
I looked at the compiler's implementation, and it seems like it *maybe*
could take better advantage of interning. The difference is a handful of
casts, some jumps, and some virtual function calls. Which isn't *great*
but won't yield more than a modicum of improved performance.
> I also don't see why you'd need to do this comparison often (assuming
> good hash functions are used.)
The current hash function simply sums symbol pointers and integer values
in the template arguments. It ignores all other values. So if I have a
simple template:
template Just(T, T value)
{
enum T Just = value;
}
All instantiations with T=double will hash to the same value. When I
tested this with 5,000 instantiations, it took twice as long with doubles
as with longs (1.07s vs 0.50s). At 10,000, over three times as long
(6.89s vs 2.05s). Short strings perform about the same as doubles.
TemplateInstance uses druntime's associative arrays, which are standard
hashtables. The interaction has some wonky parts:
* It starts out with eight buckets.
* It grows by a factor of four.
* Hashes tend to be sums of pointers.
* Pointers are aligned.
This means you're in collision city most of the time.
I tried addressing that, but I'm seeing no improvement, so I obviously
did something wrong. (And then I messed up an invocation of `find` and
deleted my entire dmd source tree, including the .git directory...)
> All in all, it would probably be best to have some degenerate code so
> that the issue can be investigated on a common footing.
I agree entirely.
More information about the Digitalmars-d
mailing list