scolebourne at joda.org
Thu Jan 12 18:12:49 UTC 2017
Fat fingers - should have been 1.8.0_112
The code is in the link:
where a HandleMetaBean (method handle) performs the same job as
LightMetaBean (reflection) as shown in the non-JMH test
The method handle setup code is all done in static initializers. The
performance tests are all testing runtime usage, excluding the static
initializer setup cost (as one off startup costs are not relevant to
my use case).
Thanks for taking a look. Its the constructor invocation that is most
obviously a problem. In HandleMetaBean.build(Object) where it uses
invokeWithArguments(Object). I get 1650ms for reflection vs 3500ms
for method handles.
The meta-property getter code runs much quicker, so a JMH test would
really be needed to confirm the difference there.
The asType() and invokeExact() code was added to see if that made a
difference, but it did not.
I saw you post when researching before writing my mail today. The code
cannot use static final method handles (I doubt there are many use
cases for those, to be honest). The goal of the code here is to obtain
an object implementing my interfaces that can be invoked in a general
way to invoke a constructor or a getter. As such, the method handles
need to be instance variables.
I have now done a JMH test.
The good news is that the method handle for the getter is slightly
faster when taken in isolation:
JodaBenchmark.testMethodHandleGet avgt 50 8.421 ± 0.078 ns/op
JodaBenchmark.testReflectionGet avgt 50 11.003 ± 0.050 ns/op
The bad news is that the method handle constructor call is not 2x
reflection, but 6x:
JodaBenchmark.testMethodHandleBuild avgt 50 219.212 ± 2.400 ns/op
JodaBenchmark.testReflectionBuild avgt 50 36.012 ± 0.167 ns/op
This test reduced the difference to :
return (T) constructorHandle.invokeWithArguments(args);
Email me privately for a zip of the JMH test:
Any thoughts on the 6x slower call? thanks for looking
On 12 January 2017 at 14:47, Claes Redestad <claes.redestad at oracle.com> wrote:
> Hi Stephen,
> this is surprising; handles should typically be as fast or much
> faster than reflection (VarHandles can be faster than Unsafe in certain
> cases), but may carry a slightly more expensive setup cost - do you have a
> reproducer I could try?
> 8b122 - do you mean 8u122 EA?
> On 2017-01-12 15:23, Stephen Colebourne wrote:
>> I've recently tried  converting Joda-Beans use of setAccessible()
>> to use MethodHandle. Since it is a code generator, the actual coding
>> is relatively easy, and obtaining the MethodHandles.Lookup instance
>> with the "private" capability is simple. While the MethodHandles API
>> looks very complex, it isn't too bad to use, although it is
>> undoubtedly more complex than reflection.
>> (Note that the standard Joda-Beans technique is to code generate
>> normal Java code to avoid the need to use reflection, but it can
>> optionally generate reflection-based code in "light bean" mode. It is
>> that reflection approach that is being examined here).
>> The real problem however is performance. In my tests, I am seeing a
>> MethodHandle approach being 2 to 3 times slower than a reflection
>> approach for identical functionality, which is quite a significant
>> degradation. (using Java 8 b122)
>> Given the performance, I left to question whether the repeated Jigsaw
>> advice to use MethodHandle instead of setAccessible is viable - in the
>> kinds of places that use reflection, performance tends to be critical.
>> Is there, or has there been, work in Java 9 to improve the performance
>> of method handles?
>>  https://github.com/JodaOrg/joda-beans/commits/wip/methodhandles
More information about the jigsaw-dev