MethodHandle.invoke* performance

Julien Ponge julien.ponge at gmail.com
Wed Apr 3 10:00:02 PDT 2013


Remi, 


Did you publish Dalvik changes somewhere? (or plan to?)


Cheers

On Wed, Apr 3, 2013 at 6:32 PM, Remi Forax <forax at univ-mlv.fr> wrote:

> On 04/03/2013 06:12 PM, Cédric Champeau wrote:
>> Le 03/04/2013 17:50, Remi Forax a écrit :
>>> Sorry to be rude, but it's still a micro-benchmark ...
>> First of all, yes, it is :) And as the classical fibonacci benchmark,
>> it's useless but relevant for understanding how things work :)
>>> for invokedynamic, it's not in theory, if your method handle is constant
>>> either because it's a static final or because it is nested in a
>>> CallSite, it's constant for the JIT, thus fully optimized.
>>>
>>> for method handle on stack, the method handle is obviously not constant
>>> moreover the JIT is not able use trick to make it constant (like
>>> hoisting it out of the loop,
>>> or doing the inlining algorithm in a backward way etc.)
>>> More on that later ...
>> Well, even if I make my MH variable declaration "final", the performance
>> is the same, so I assume there's no local analysis, right?
> 'final' on a local variable is a modifier for the compiler, not for the JIT.
> There are several local analysis, but not the ones you think.
>>> As you said it's a micro-benchmark so you end up with unusual good
>>> performance,
>>> by example the call to j.l.r.Method is optimized as never it will be in
>>> a real program
>>> (you call the method in the same unit it was declared and
>>> you have less than 3 instances of Method that are called more than 60
>>> times).
>>>
>>> Now, Krystal is currently working to add a cache when a method handle is
>>> called,
>>> so in few betas, the performance of method handles of your
>>> micro-benchmark will improve dramatically.
>> That's good to know :)
>>> And the cache of MethodHandle is better that the cache which is used for
>>> j.l.r.Method because it can be local to a callsite and not global (in
>>> fact local to one callsite in the code of j.l.r.Method that is used by
>>> the invocation path when you call "invoke").
>>>
>>> Anyway, because it's a micro-benchmark the result will be as useless as
>>> now to predict the behaviour of a real world program.
>> I can perfectly understand why some path is optimized or not, what I
>> find surprising is more the order of magnitude here. So yes, calling
>> invoke() takes more than 50s where reflection takes only 1.2s, and even
>> invokeExact is slower (~3 to 1). My point is more than if MethodHandles
>> are branded as "faster" than reflection (I heard you say it ;)), then
>> there is something wrong.
> I say that in the context of proxies, i.e. where you can emit an 
> invokedynamic to store the method handle at callsite, method handle are 
> faster than using reflection because you don't need proxies anymore 
> (remember I said that too :).
>> You should expect people doing stupid things  like me, thinking it will be faster than plain reflection. At least, the  docs should mention something about performance.
> The javadoc is the spec, we are talking about the Oracle implementation 
> of the spec.
> On Android, Jerome and I have run some tests that shows that a 
> MethodHandle.invokeExact is always faster than a call to the Reflection, 
> it's just because the reflection is super slow on Android not the opposite.
>>> cheers,
>>> Rémi
>> Thanks for your answer :)
> Rémi
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20130403/2e26d495/attachment.html 


More information about the mlvm-dev mailing list