Doing a quick JMH benchmark here, with a constructor taking 4 arguments, invokeWithArguments was about 15-30x slower than invoke and invokeExact. Otherwise, static final MH was 2.5x faster then reflection, and instance field MH was 1.3x faster
For output and test code: https://gist.github.com/anonymous/32e698d04c7456c10f069686072d7cc6 /Michael On 12 January 2017 at 20:12, Stephen Colebourne <scolebou...@joda.org> wrote: > @Claes > > Fat fingers - should have been 1.8.0_112 > > The code is in the link: > https://github.com/JodaOrg/joda-beans/commit/ad7d61a7ff72f932957127117dd8f377e1e2bf60 > > where a HandleMetaBean (method handle) performs the same job as > LightMetaBean (reflection) as shown in the non-JMH test > TestHandle.main(). > > @Jochen > > 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). > > @Remi > 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. > > @Aleksey > 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); > vs > return constructor.newInstance(args); > > Email me privately for a zip of the JMH test: > > Any thoughts on the 6x slower call? thanks for looking > Stephen > > > On 12 January 2017 at 14:47, Claes Redestad <claes.redes...@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? >> >> Thanks! >> >> /Claes >> >> >> On 2017-01-12 15:23, Stephen Colebourne wrote: >>> >>> I've recently tried [1] 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? >>> >>> Stephen >>> >>> [1] https://github.com/JodaOrg/joda-beans/commits/wip/methodhandles >>> >>