Optimizing delegates

Daniel Gibson metalcaedes at gmail.com
Sun Dec 19 12:47:06 PST 2010


On Sun, Dec 19, 2010 at 5:44 PM, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:
> On 12/19/10 10:35 AM, Ary Borenszweig wrote:
>>
>> On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote:
>>>
>>> On 12/19/10 9:32 AM, Ary Borenszweig wrote:
>>>>
>>>> I have this code:
>>>>
>>>> ---
>>>> import std.stdio;
>>>>
>>>> int foobar(int delegate(int) f) {
>>>> return f(1);
>>>> }
>>>>
>>>> int foobar2(string s)() {
>>>> int x = 1;
>>>> mixin("return " ~ s ~ ";");
>>>> }
>>>>
>>>> void main() {
>>>> writefln("%d", foobar((int x) { return 2*x; }));
>>>> writefln("%d", foobar2!("9876*x"));
>>>> }
>>>> ---
>>>>
>>>> When I compile it with -O -inline I can see with obj2asm that for the
>>>> first writefln the delegate is being called. However, for the second
>>>> it just passes
>>>> 9876 to writefln.
>>>>
>>>> From this I can say many things:
>>>> - It seems that if I want hyper-high performance in my code I must use
>>>> string mixins because delegate calls, even if they are very simple and
>>>> the
>>>> functions that uses them are also very simple, are not inlined. This
>>>> has the drawback that each call to foobar2 with a different string
>>>> will generate a
>>>> different method in the object file.
>>>
>>> You forgot:
>>>
>>> writefln("%d", foobar2!((x) { return 2*x; })());
>>>
>>> That's a real delegate, not a string, but it will be inlined.
>>>
>>>
>>> Andrei
>>
>> Sorry, I don't understand. I tried these:
>>
>> 1.
>> int foobar3(int delegate(int) f)() {
>> return f(1);
>> }
>>
>> writefln("%d", foobar3!((int x) { return 2*x; })());
>>
>> => foo.d(12): Error: arithmetic/string type expected for
>> value-parameter, not int delegate(int)
>>
>> 2.
>> int foobar3()(int delegate(int) f) {
>> return f(1);
>> }
>>
>> writefln("%d", foobar3!()((int x) { return 2*x; }));
>>
>> => Works, but it doesn't get inlined.
>>
>> And I tried that "(x) { ... }" syntax and it doesn't work.
>>
>> Sorry, it must be my fault I'm doing something wrong. What's the correct
>> way of writing optimized code in D, code that I'm sure the compiler will
>> know how to optimize?
>
> void foobar3(alias fun)() {
>    return fun(1);
> }
>
>
> Andrei
>

I think using an alias makes the code less readable.
"int foobar(int delegate(int) f)" tells you that the argument should be (a
delegate of) a function that accepts an int and returns an int.
"foobar3(alias fun)()" tells you almost nothing. You know that some kind of
template parameter is expected, but not if it's a function or whatever, and
even less what signature that function should have.

IMHO some other syntax than just "alias fun" should be used for this purpose
(inlined delegates known at compile time) - some syntax that documents the
 signature of the expected function, like with real delegates.

 Cheers,
 - Daniel


More information about the Digitalmars-d mailing list