New blog post on the cost of compile time
Steven Schveighoffer
schveiguy at gmail.com
Thu Jan 19 15:19:06 UTC 2023
On 1/18/23 5:20 PM, Walter Bright wrote:
> On 1/17/2023 1:58 PM, H. S. Teoh wrote:
>> If the
>> language had instead been extended so that you could, for example,
>> extract the return type of some given callable directly, say
>> typeof(return(myfunc)), then none of this would have been necessary in
>> the first place.
>
> https://dlang.org/spec/expression.html#is_expression
>
> int func();
>
> static if (is(typeof(func) R == return))
> pragma(msg, R);
>
> prints:
>
> int
>
> The implementation of std.traits.ReturnType is:
>
> template ReturnType(alias func)
> if (isCallable!func)
> {
> static if (is(FunctionTypeOf!func R == return))
> alias ReturnType = R;
> else
> static assert(0, "argument has no return type");
> }
>
> ReturnType can do a little more than the raw IsExpression, as it can
> identify:
>
> struct G
> {
> int opCall (int i) { return 1;}
> }
>
I didn't think of making ReturnType simplified (we know in this case the
thing is not anything except a normal lambda function). I did this now:
```d
template RT(alias sym) {
static if(is(typeof(sym) R == return))
alias RT = R;
else
static assert(false, "bad");
}
...
else version(useIsExpr)
{
enum isInputRange(R) = is(typeof(R.init) == R)
&& is(RT!((R r) => r.empty) == bool)
&& (is(typeof((return ref R r) => r.front)) || is(typeof(ref
(return ref R r) => r.front)))
&& !is(RT!((R r) => r.front) == void)
&& is(typeof((R r) => r.popFront));
}
```
The result is still not as good as just using typeof directly, but much
much better. When compared to a direct typeof, it adds about 0.15s of
total compile time for 10000 instances, and adds 100MB more memory usage.
My point still stands -- *inside* a constraint template, you should
avoid using all kinds of convenience templates if you can help it.
Nobody cares about the implementation of `isInputRange`, as long as it
gives the right answer.
Now, Adam has a point (in his comment on my blog) that if you are
*already* using such convenience templates elsewhere on the *same
parameters*, then this can have a negative effect on overall
performance, because the caching of the template answer can speed up the
compilation. In this case, the template instantiation is guaranteed to
be unique since these are lambda expressions, so that doesn't apply.
I think we can all agree though that it is less than ideal to have to
worry about the internal details of how templates are implemented.
-Steve
More information about the Digitalmars-d
mailing list