New library: open multi-methods
Jean-Louis Leroy via Digitalmars-d-announce
digitalmars-d-announce at puremagic.com
Tue Jul 18 11:34:39 PDT 2017
On Tuesday, 18 July 2017 at 16:57:30 UTC, Ali Çehreli wrote:
> > As for performance, I have a first result:
> >
> https://github.com/jll63/methods.d/blob/master/benchmarks/source/benchmarks.d#L122
> > but I still have to implement the "first argument
> optimization". I am
> > working on it.
>
> I could use some explanation for the results but I can for the
> blog article. ;)
I pit a method-based call against its equivalent using virtual
functions. First calling a virtual function via a base class is
pitted against a method with one virtual parameter. Then the same
but calling via an interface. Lastly, I compare double dispatch
with a method with two virtual arguments. I use
std.datetime.comparingBenchmark, which reports the result as
time(base)/time(target). So open methods are a bit slower than
ordinary virtual function calls but not that much. In the
meantime I have applied a second optimization for unary methods
and this brings them within 33% of an ordinary, compiler
implemented vfunc call. Which is OK because the situation is
highly artificial. If the function does anything, the difference
will be imperceptible.
I am more annoyed by double dispatch beating binary methods. I
will have to look at the assembler, but it may be that the index
pointer is too far from the object. To begin the real work, I
need to fetch that pointer form an object. Currently it is stored
in ClassInfo.deallocator, so I have to 1/ fetch the vptr 2/ fetch
the ClassInfo* 3/ fetch 'deallocator'. What happens next depends
on the arity.
Any chance of Walter giving me a pointer in the vtable? Aside the
ClassInfo*? Or at least a pointer in ClassInfo, or reassign the
deallocator when it is eventually retired?
> It's not surprising that ldc (and gdc) can be much better than
> dmd in optimization.
I would like to try gdc but it conflicts with ldc2 - you know,
the "alias __va_list = __va_list_tag;" issue. I found suggestions
via google but nothing worked for me so far.
>
> By the way, I'm in awe of your D skills in such a short time!
Thanks :) I found out that D was much more natural, "predictable"
than C++. The most cryptic error messages happened when I forgot
the "!", IIRC.
> I'm sure there are parts of the code that can be cleaned up but
> it's taking advantage of many powerful features of the
> language. I still think the usage can be made easier but I'm
> not sure yet. I hope others will take a look at the code and
> come up with an easier interface. Perhaps they are all needed
> but I'm thinking about the need for forward declaration, the
> need for the underscore prefix, etc.
(in reverse order)
Regarding the prefix, it is needed to prevent overload resolution
from trumping dynamic dispatch - see here:
https://github.com/jll63/methods.d/blob/master/examples/whytheunderscore/source/app.d Allowing the same name would necessitate compiler support.
As for the the forward declaration - I don't think it is possible
to dispense with it. All open methods systems I know of have it
(defgeneric in CLOS, defmulti in Clojure, Stroustrup's
proposal...). Consider:
class A { }
class B : A { }
class X : B { }
class Y : B { }
@method void _foo(virtual!X x) { ... }
@method void _foo(virtual!Y x) { ... }
What is the base method? foo(B)? foo(A)? It may well be the
latter. Also don't forget that the complete specialization set is
known, at the earliest, at link time. If you (arbitrarily) pick
foo(B), another module may introduce a B or an A specialization.
As for suggestions and advise, they are very welcome :) already
got a couple of PRs. Here are the remaining questions on my mind:
- the module/package name: I am pretty much set on openmethods
though...
- throw an exception if a method is not define for the argument
set, or ambiguous: having big doubts about this. We want the
possibility of @nothrow methods, don't we? So I will probably
call a delegate via a pointer (a la C++) which, by default, will
abort().
- the method prefix: hesitating between just _ or maybe m_ ???
- replace version(explain) with debug levels?
More information about the Digitalmars-d-announce
mailing list