MethodHandle vs invodynamic (performance-wise)

forum at x9c.fr forum at x9c.fr
Sun Feb 13 10:00:24 PST 2011


Le 13 févr. 2011 à 12:55, Rémi Forax a écrit :

> On 02/13/2011 10:07 AM, forum at x9c.fr wrote:
>> Dear list,
>> 
>> In a previous thread (that I cannot find again), I read that better
>> performances could be achieved via the "invokedynamic" instruction
>> rather than by using "MethodHandle" instances.
>> However, it is not clear to me whether this is true only for the
>> current state of the implementation, or should remain true in the
>> future (read "at the time of JDK7 release").
> 
> It's true for all implementations if the target of invokedynamic is stable
> (don't change too often).

Thanks for the information; is there a reasonable estimate of the different
speeds (supposing that the target would indeed be constant). I mean, it
the gap as huge as between reflection and handles?


>> If useful, here is a summary about the context: implementation
>> of both an interpreter and a compiler supporting closures.
> 
> There are 2 different use cases, one is how to implement a 
> function/method call,
> in that case you should use invokedynamic. The other is how to implement 
> a closure call,
> in that case you should use MethodHandle.invoke{Exact|Generic}.
> 
> It's a little bit more complex if a callsite can call a closure or a 
> method like by example
> the method 'call' in Groovy. In that case, you can use an invokedynamic 
> and if the first parameter
> is a MethodHandle and use the MHs.genericInvoker (or MHs.exactInvoker) 
> as target MethodHande.
> 
> Anyway, as you see you should choose to use one mechanism or the other 
> depending
> on the use case and not on some benchmark.

Well, I do not fully understand your point. To some extend, it appears to me
that both mechanisms can be used to achieve the very same effect. That's
why I thought the "director's cut" should be performances.


>> Please note that for interoperability reasons, it will not be possible
>> to use built-in currification-like support provided by handles.
>> Hence, all calls will be "total".M
>> 
>> Thanks in advance for any insight.
> 
> In you case, you can:
> - use MethodHandle instead of j.l.r.Method when doing native call.

This is actually what is done in (unreleased) code.
This resulted in a huge speed-up, but was wondering if I should use
"invokedynamic" instead.


> - use invokedynamic in the bytecode generated by Cafesterol and
>   implement the corresponding bootstrap methods in Cadmium.
>   AbstractNativeRunner.closures should be a list of method handles.
> - change the implementation of Value or Block to store a MethodHandle
>   in it and use it as a closure instead of using the Closure object.

Well, this too has been rewritten, there is no more a list of closures but
Value/Block is now a hierarchy a specialized classes (e. g. double, 
bare block, closure). There again, I wonder if the best is to do a
"Method.InvokeExact(-)" or to play with the "invokedynamic" instruction.
The former has been implemented easily and is indeed quite fast.
Is it a good investment to move to le latter, given that it will
probably entail compile-time generation of one class per target in
my case ?


Thanks for the thorough information.

Kind regards,

Xavier Clerc



More information about the mlvm-dev mailing list