speed of invokeExact
Jochen Theodorou
blackdrag at gmx.org
Thu May 9 02:26:03 PDT 2013
Am 08.05.2013 23:12, schrieb John Rose:
> On May 8, 2013, at 5:33 AM, Jochen Theodorou <blackdrag at GMX.ORG> wrote:
>
>> Am 07.05.2013 19:31, schrieb Christian Thalinger:
>> [...]
>>> Do you have any numbers?The problem is that if the MH is not constant
>>> we can't do any inlining and it will be an out-of-line call (with a trampoline in between). Is
>>> your DMH a static or virtual?
>>
>> arg... looks like I made a mistake. It is not the invokeExact that is
>> slow, it is my preparation of the handle that is slow.
>
> So it's an insertArgs and asType that's slow. Can you distill the operations into a micro-benchmark for us?
to reduce it to only asType:
compare the times of this:
> MethodHandle mh = MethodHandles.lookup().findVirtual(String.class, "toString", MethodType.methodType(String.class));
> int tmax = 1_000_000;
> for (int k=0; k<20; k++) {
> long t1 = System.nanoTime();
> for (int i=0; i<tmax; i++) {
> String s = (String) mh.invokeExact(str);
> }
> long t2 = System.nanoTime();
> System.out.println((t2-t1)/tmax);
> }
with this:
> MethodHandle mh = MethodHandles.lookup().findVirtual(String.class, "toString", MethodType.methodType(String.class));
> MethodType invokeType = MethodType.methodType(Object.class, String.class);
> int tmax = 1_000_000;
> for (int k=0; k<20; k++) {
> long t1 = System.nanoTime();
> for (int i=0; i<tmax; i++) {
> MethodHandle invoker = mh.asType(invokeType);
> Object o = invoker.invokeExact(str);
> }
> long t2 = System.nanoTime();
> System.out.println((t2-t1)/tmax);
> }
The first one has times of about 9-15 on my machine, the later one
800-900. I am aware that this is a test in which hotspot should throw
out the invocation completely, but it does not. Even more interesing is
when you reduce the test even further:
> MethodHandle mh = MethodHandles.lookup().findVirtual(String.class, "toString", MethodType.methodType(String.class));
> MethodType invokeType = MethodType.methodType(Object.class, String.class);
> int tmax = 1_000_000;
> for (int k=0; k<20; k++) {
> long t1 = System.nanoTime();
> for (int i=0; i<tmax; i++) {
> MethodHandle invoker = mh.asType(invokeType);
> }
> long t2 = System.nanoTime();
> System.out.println((t2-t1)/tmax);
> }
Now this should really be optimized away completely by hotspot, but is
not and takes about the same time as the second case... which is not
surprising since the asType call is totally dominating the "benchmark".
btw, the test was with a jdk 1.8.0 ea with tiered compilation turned
off. The tests contain no warmup, but that's what why the test is
repeated 20 times to see the development of the values instead of doing
a one time measurement. And the values in this test go up and down a lot too
bye blackdrag
--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org
More information about the mlvm-dev
mailing list