On 12/19/2010 01:57 PM, Ary Borenszweig wrote:
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.

Oops, sorry, it does get inlined, my mistake. I will submit a patch to DMD right now with the above error.

Reply via email to