"Ary Borenszweig" <a...@esperanto.org.ar> wrote in message 
news:ieldl1$1of...@digitalmars.com...
> On 12/19/2010 01:44 PM, Andrei Alexandrescu 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
>
> foo.d
> ---
> import std.stdio;
>
> int foobar3(alias f)() {
>    return f(1);
> }
>
> void main() {
>    writefln("%d", foobar3!((x) { return 9876*x; })());
> }
>
> aster...@deep-water:~/dmd2/linux/bin$ ./dmd foo.d -O -inline
> aster...@deep-water:~/dmd2/linux/bin$ ./obj2asm foo.o | vi -
> (line 530)
> _Dmain:
> push EBP
> mov EBP,ESP
> mov EAX,offset FLAT:_d3std5stdio6stdouts3std5stdio4f...@sym32
> push dword ptr _t...@sym32[0eh]
> push dword ptr _t...@sym32[010h]
> push 02694h
> call   _d3std5stdio4file19__t8writeflntayatiz8writeflnmfaya...@pc32
> xor EAX,EAX
> pop EBP
> ret
> nop
> nop
>
> No, it doesn't seem to get inlined. Luckily. Because if it did get inlined 
> then I would improve DMD by giving an error on this line:
>
> int foobar(int delegate(int) f) {
>  ...
> }
>
> foo.d(3): Error: Hey man, what are you doing? Don't you know that if you 
> pass delegates that way they don't get inlined? You should write it this 
> way: "int foobar(alias f)()". That is, of course, if you want your code to 
> be more performant.

It's not completely useless: "int foobar(int delegate(int) f) { }" allows 
you to choose what delegate to send at run-time. "int foobar3(alias f)() 
{ }" doesn't. (Although, I suppose you might be able to work around that 
moving the run-time selection from the caller of foobar3 to the delegate 
passed into "int foobar3(alias f)() { }". Not sure if there are cases where 
that would be awkward to do.)

I will say though, it's a hell of a lot easier to remember the syntax of 
"int foobar(alias f)()".  :)


Reply via email to