digitalmars.D - multiple dispatch using run & compile time reflection
- Christian Kamm (48/48) Jul 24 2007 I was experimenting with the new __traits and used it to create a
- Pragma (6/69) Jul 24 2007 Neat.
- Christian Kamm (6/10) Jul 24 2007 I hope so. For testing I used empty function bodies (they weren't optimi...
- Craig Black (7/56) Jul 24 2007 This is very cool! Is it necessary to place all methods inside a single...
I was experimenting with the new __traits and used it to create a RTTI-dispatched visitor here: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D.announce&artnum=9348 I've extended the code to allow multiple dispatch and be a bit more generic. The code is attached, an example is inline: ---- import multipledispatch, std.stdio; class A {} class B : A {} class Foo { void bar(A a1, A a2) { writefln("AA"); } void bar(A a, B b) { writefln("AB"); } void bar(B a, B b) { writefln("BB"); } // generates void dispatch(Object,Object) // that uses RTTI to call one of the overloads // defined above mixin MultipleDispatch!("bar", _0, _1); } void main() { A a = new A; A b = new B; auto foo = new Foo; foo.dispatch(a, a); // writes AA foo.dispatch(a, b); // writes AB foo.dispatch(b, b); // writes BB foo.dispatch(b, a); // throws error } ---- I have also included a MultipleDispatchFallthrough template that'll call the best match instead of throwing an error if there's no exact match. However, the implementation is pretty inefficient. (feel free to optimize) Here are some rough benchmarks, relative to a virtual function call: virtual function call: 1 MultipleDispatch with one DispatchArg: 2.5 MultipleDispatch with three DispatchArgs: 2.9 MultipleDispatch with one DispatchArg and Fallthrough: 10 As you can see, a call through MultipleDispatch will take roughly three times as long as a virtual function call. Since a call to dispatch will contain two virtual function calls, that's almost optimal. Regards, Christian
Jul 24 2007
Christian Kamm wrote:I was experimenting with the new __traits and used it to create a RTTI-dispatched visitor here: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D.announce&artnum=9348 I've extended the code to allow multiple dispatch and be a bit more generic. The code is attached, an example is inline: ---- import multipledispatch, std.stdio; class A {} class B : A {} class Foo { void bar(A a1, A a2) { writefln("AA"); } void bar(A a, B b) { writefln("AB"); } void bar(B a, B b) { writefln("BB"); } // generates void dispatch(Object,Object) // that uses RTTI to call one of the overloads // defined above mixin MultipleDispatch!("bar", _0, _1); } void main() { A a = new A; A b = new B; auto foo = new Foo; foo.dispatch(a, a); // writes AA foo.dispatch(a, b); // writes AB foo.dispatch(b, b); // writes BB foo.dispatch(b, a); // throws error } ---- I have also included a MultipleDispatchFallthrough template that'll call the best match instead of throwing an error if there's no exact match. However, the implementation is pretty inefficient. (feel free to optimize) Here are some rough benchmarks, relative to a virtual function call: virtual function call: 1 MultipleDispatch with one DispatchArg: 2.5 MultipleDispatch with three DispatchArgs: 2.9 MultipleDispatch with one DispatchArg and Fallthrough: 10 As you can see, a call through MultipleDispatch will take roughly three times as long as a virtual function call. Since a call to dispatch will contain two virtual function calls, that's almost optimal. Regards, ChristianNeat. I gather that since you're using near-trival function bodies for testing, these timings represent the relative call dispatch overhead? If so, then that's great research - thanks. -- - EricAnderton at yahoo
Jul 24 2007
Neat.Thanks! Experimenting with the new functionality was fun.I gather that since you're using near-trival function bodies for testing, these timings represent the relative call dispatch overhead?I hope so. For testing I used empty function bodies (they weren't optimized away; the empty loop finished significantly faster) and an average over ten million calls. It might get worse if there are a lot of overloads, but I don't think by much.
Jul 24 2007
This is very cool! Is it necessary to place all methods inside a single class? It is sometimes necessary to allow multimethods to be extended in multiple classes. I figure there's probably a way to do this with an approach similar to this. -Craig "Christian Kamm" <kamm.incasoftware shift-at-left-and-remove-this.de> wrote in message news:f84ufe$27e3$1 digitalmars.com...I was experimenting with the new __traits and used it to create a RTTI-dispatched visitor here: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D.announce&artnum=9348 I've extended the code to allow multiple dispatch and be a bit more generic. The code is attached, an example is inline: ---- import multipledispatch, std.stdio; class A {} class B : A {} class Foo { void bar(A a1, A a2) { writefln("AA"); } void bar(A a, B b) { writefln("AB"); } void bar(B a, B b) { writefln("BB"); } // generates void dispatch(Object,Object) // that uses RTTI to call one of the overloads // defined above mixin MultipleDispatch!("bar", _0, _1); } void main() { A a = new A; A b = new B; auto foo = new Foo; foo.dispatch(a, a); // writes AA foo.dispatch(a, b); // writes AB foo.dispatch(b, b); // writes BB foo.dispatch(b, a); // throws error } ---- I have also included a MultipleDispatchFallthrough template that'll call the best match instead of throwing an error if there's no exact match. However, the implementation is pretty inefficient. (feel free to optimize) Here are some rough benchmarks, relative to a virtual function call: virtual function call: 1 MultipleDispatch with one DispatchArg: 2.5 MultipleDispatch with three DispatchArgs: 2.9 MultipleDispatch with one DispatchArg and Fallthrough: 10 As you can see, a call through MultipleDispatch will take roughly three times as long as a virtual function call. Since a call to dispatch will contain two virtual function calls, that's almost optimal. Regards, Christian
Jul 24 2007