Optimizing delegates

loser noneedtotalkanymore at to.me
Sun Dec 19 16:06:34 PST 2010


Daniel Gibson Wrote:

> 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.

Hear, hear. Another problem with this approach I couldn't even think of. With luck, illegal code may compile. You have no clean way to enforce/document the domain of the comparator/predicate.


More information about the Digitalmars-d mailing list