(Related: https://d.puremagic.com/issues/show_bug.cgi?id=10848)
If you have a function, that needs to do a test/assert, and does it via a lambda block (for example, to declare a variable), then that function will not be inline-able.
This seems really crazy to me, since the lambda only exists during compilation anyways. This affects DMD, but not GDC.
Here is a test program. It's a reduced case of what currently happens when we call "std.array.array".
Variant 1 contains:
static assert(is(typeof(*chunk = arg)));
Whereas 2 contains:
static assert(is(typeof({*chunk = arg;})));
//----
import std.stdio;
import std.datetime;
void array1(int[] arr)
{
foreach (int i, e ; arr)
{
emplace1(&e, i);
++i;
}
}
void emplace1(T, Arg)(T* chunk, Arg arg)
{
static assert(is(typeof(*chunk = arg)));
*chunk = arg;
}
void array2(T)(T[] arr)
{
foreach (int i, e ; arr)
{
emplace2(&e, i);
++i;
}
}
void emplace2(T, Arg)(T* chunk, Arg arg)
{
static assert(is(typeof({*chunk = arg;})));
*chunk = arg;
}
void main()
{
auto arr = new int[] (10_000);
StopWatch st1;
st1.start;
foreach (__; 0 .. 20_00)
{
array1(arr);
}
st1.stop;
StopWatch st2;
st2.start;
foreach (__; 0 .. 20_00)
{
array2(arr);
}
st2.stop;
writefln("1");
writefln("Time: %sms", st1.peek.msecs);
writefln("2");
writefln("Time: %sms", st2.peek.msecs);
}
//----
Resulting times:
1
Time: 11ms
2
Time: 1972ms
:/
EDIT: I'm *assuming* it's an inline problem, I haven't look at the ASM. But I don't see how it could be anything else...
Comment #3 by monarchdodra — 2013-11-12T07:03:35Z
Hum... I did some more investigating, and it would appear the culprit is not "just" having a lambda, but rather, having a lambda that needs access to context. EG:
static assert(is(typeof(*chunk = arg))); //FAST
static assert(is(typeof({*chunk = Arg.init;))); //FAST
static assert(is(typeof({*chunk = arg;}))); //SLOW
Comment #4 by monarchdodra — 2013-11-12T09:20:26Z
(In reply to comment #3)
> Hum... I did some more investigating, and it would appear the culprit is not
> "just" having a lambda, but rather, having a lambda that needs access to
> context. EG:
>
> static assert(is(typeof(*chunk = arg))); //FAST
> static assert(is(typeof({*chunk = Arg.init;))); //FAST
> static assert(is(typeof({*chunk = arg;}))); //SLOW
Typo:
static assert(is(typeof(*chunk = arg))); //FAST
static assert(is(typeof({*chunk = Arg.init;}))); //FAST
static assert(is(typeof({*chunk = arg;}))); //SLOW
(In reply to comment #5)
> Also related: https://d.puremagic.com/issues/show_bug.cgi?id=11483
Nice. So indeed, it's not an inlining problem.
I *thought* the results were way too catastrophic for a simple inline problem.
Comment #7 by github-bugzilla — 2013-11-17T19:47:18Z