Hi, I am Alex Turner - I was working on a COBOL to JVM compiler and am now helping with a Magik to JVM compiler. I thought I might just confirm that invokeExact has proven a lt ot quicker than invoke in our tests. We have also noticed that using a method adapter to convert argument counts makes things a little slower (a few percent). But using an adapter then invokeExact is much faster than using invoke.
My approach from here is to try very hard to avoid invoke and only use it when there is no realistic chance of resolving an invokeExact for more than one call. Best wishes - AJ On 9 July 2011 14:08, Hiroshi Nakamura <nakah...@gmail.com> wrote: > Hello, > > Thanks for your swift responses. > > On Sat, Jul 9, 2011 at 19:29, Rémi Forax <fo...@univ-mlv.fr> wrote: >>> You should avoid to create constants more than once. > > Indeed. I updated the benckmark. (please see below) > >>> Also, bindTo() will create a method handle for-each call. > > Sure, but 'bindTo(rec).invokeExact(arg)' looks faster than > 'invoke(rec, arg)' for this microbenchmark. > >>> or like that: >>> >>> private static final MethodHandles.Lookup lookup = >>> MethodHandles.lookup(); >>> private static final MethodType mt = >>> MethodType.methodType(String.class, String.class); >>> private static final MethodType mt2 = >>> MethodType.methodType(String.class, Object.class, String.class); >>> >>> private static MethodHandle methodhandleLookup(Object receiver, >>> String methodName) throws Throwable { >>> MethodHandle mh = lookup.findVirtual(receiver.getClass(), >>> methodName, mt); >>> return mh.asType(mt2); >>> } >>> >>> private static String methodhandleInvoke(Object receiver, >>> MethodHandle method) throws Throwable { >>> return (String) method.bindTo(receiver).invokeExact(receiver, >>> "methodhandle"); >>> } >> >> oups, typo: >> >> private static String methodhandleInvoke(Object receiver, MethodHandle >> method) throws Throwable { >> return (String) method.invokeExact(receiver, "methodhandle"); >> } > > Thank you very much. I didn't understand asType well. > > Here's the updated code: > https://raw.github.com/nahi/jsr292-sandbox/master/src/jp/gr/java_conf/jruby/MethodHandleTest.java > and the benchmark result follows. I updated 'methodhandle' as > 'methodhandle1' to use constants, and added 'methodhandle2' which uses > 'asType'. Interestingly, 'methodhandle2' invocation perf got as fast > as reflection, but lookup got slower than 'methodhandle1'. > > -- 0 > methodhandle1 lookup * 100000: 557.97 [msec], average: 5.58 [nsec] > methodhandle1 lookup+invoke * 100000: 431.21 [msec], average: 4.31 [nsec] > methodhandle2 lookup * 100000: 413.81 [msec], average: 4.14 [nsec] > methodhandle2 lookup+invoke * 100000: 297.56 [msec], average: 2.98 [nsec] > reflection lookup * 100000: 99.52 [msec], average: 1.00 [nsec] > reflection lookup+invoke * 100000: 181.40 [msec], average: 1.81 [nsec] > -- 1 > methodhandle1 lookup * 100000: 192.42 [msec], average: 1.92 [nsec] > methodhandle1 lookup+invoke * 100000: 289.65 [msec], average: 2.90 [nsec] > methodhandle2 lookup * 100000: 267.24 [msec], average: 2.67 [nsec] > methodhandle2 lookup+invoke * 100000: 327.26 [msec], average: 3.27 [nsec] > reflection lookup * 100000: 38.44 [msec], average: 0.38 [nsec] > reflection lookup+invoke * 100000: 65.53 [msec], average: 0.66 [nsec] > -- 2 > methodhandle1 lookup * 100000: 176.79 [msec], average: 1.77 [nsec] > methodhandle1 lookup+invoke * 100000: 270.87 [msec], average: 2.71 [nsec] > methodhandle2 lookup * 100000: 259.02 [msec], average: 2.59 [nsec] > methodhandle2 lookup+invoke * 100000: 289.60 [msec], average: 2.90 [nsec] > reflection lookup * 100000: 31.77 [msec], average: 0.32 [nsec] > reflection lookup+invoke * 100000: 104.24 [msec], average: 1.04 [nsec] > -- 3 > methodhandle1 lookup * 100000: 220.45 [msec], average: 2.20 [nsec] > methodhandle1 lookup+invoke * 100000: 282.01 [msec], average: 2.82 [nsec] > methodhandle2 lookup * 100000: 265.23 [msec], average: 2.65 [nsec] > methodhandle2 lookup+invoke * 100000: 299.53 [msec], average: 3.00 [nsec] > reflection lookup * 100000: 39.24 [msec], average: 0.39 [nsec] > reflection lookup+invoke * 100000: 70.76 [msec], average: 0.71 [nsec] > -- 4 > methodhandle1 lookup * 100000: 183.54 [msec], average: 1.84 [nsec] > methodhandle1 lookup+invoke * 100000: 268.61 [msec], average: 2.69 [nsec] > methodhandle2 lookup * 100000: 262.18 [msec], average: 2.62 [nsec] > methodhandle2 lookup+invoke * 100000: 284.43 [msec], average: 2.84 [nsec] > reflection lookup * 100000: 28.34 [msec], average: 0.28 [nsec] > reflection lookup+invoke * 100000: 62.86 [msec], average: 0.63 [nsec] > -- 5 > methodhandle1 lookup * 100000: 182.89 [msec], average: 1.83 [nsec] > methodhandle1 lookup+invoke * 100000: 260.14 [msec], average: 2.60 [nsec] > methodhandle2 lookup * 100000: 262.31 [msec], average: 2.62 [nsec] > methodhandle2 lookup+invoke * 100000: 284.80 [msec], average: 2.85 [nsec] > reflection lookup * 100000: 28.60 [msec], average: 0.29 [nsec] > reflection lookup+invoke * 100000: 67.08 [msec], average: 0.67 [nsec] > -- 6 > methodhandle1 lookup * 100000: 191.14 [msec], average: 1.91 [nsec] > methodhandle1 lookup+invoke * 100000: 260.52 [msec], average: 2.61 [nsec] > methodhandle2 lookup * 100000: 246.75 [msec], average: 2.47 [nsec] > methodhandle2 lookup+invoke * 100000: 282.33 [msec], average: 2.82 [nsec] > reflection lookup * 100000: 28.98 [msec], average: 0.29 [nsec] > reflection lookup+invoke * 100000: 66.73 [msec], average: 0.67 [nsec] > -- 7 > methodhandle1 lookup * 100000: 182.27 [msec], average: 1.82 [nsec] > methodhandle1 lookup+invoke * 100000: 260.33 [msec], average: 2.60 [nsec] > methodhandle2 lookup * 100000: 255.34 [msec], average: 2.55 [nsec] > methodhandle2 lookup+invoke * 100000: 290.13 [msec], average: 2.90 [nsec] > reflection lookup * 100000: 30.20 [msec], average: 0.30 [nsec] > reflection lookup+invoke * 100000: 72.33 [msec], average: 0.72 [nsec] > -- 8 > methodhandle1 lookup * 100000: 176.21 [msec], average: 1.76 [nsec] > methodhandle1 lookup+invoke * 100000: 267.92 [msec], average: 2.68 [nsec] > methodhandle2 lookup * 100000: 261.67 [msec], average: 2.62 [nsec] > methodhandle2 lookup+invoke * 100000: 285.91 [msec], average: 2.86 [nsec] > reflection lookup * 100000: 34.12 [msec], average: 0.34 [nsec] > reflection lookup+invoke * 100000: 68.78 [msec], average: 0.69 [nsec] > -- 9 > methodhandle1 lookup * 100000: 181.78 [msec], average: 1.82 [nsec] > methodhandle1 lookup+invoke * 100000: 265.34 [msec], average: 2.65 [nsec] > methodhandle2 lookup * 100000: 252.99 [msec], average: 2.53 [nsec] > methodhandle2 lookup+invoke * 100000: 299.42 [msec], average: 2.99 [nsec] > reflection lookup * 100000: 31.08 [msec], average: 0.31 [nsec] > reflection lookup+invoke * 100000: 66.65 [msec], average: 0.67 [nsec] > > Am I still missing something? > > Regards, > // NaHi > _______________________________________________ > mlvm-dev mailing list > mlvm-dev@openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > -- Dr Alexander J Turner http://nerds-central.blogspot.com/2008/01/about-me.html _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev