Quantcast
Channel: Active questions tagged methodhandle - Stack Overflow
Viewing all articles
Browse latest Browse all 36

`MethodHandle` slower than Reflection when accessing Object

$
0
0

I would like to call a method via reflection in the most performant way possible.

The method returns an Object.

I've implemented this using both reflection and MethodHandles, I was expecting MethodHandle to be faster - but that's not what I'm seeing (~20-40% slower).

Take the following JMH benchmark:

import org.openjdk.jmh.annotations.*;import java.lang.invoke.MethodHandle;import java.lang.invoke.MethodHandles;import java.lang.reflect.Method;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.NANOSECONDS)@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)@Measurement(iterations = 200, time = 10, timeUnit = TimeUnit.MILLISECONDS)@State(Scope.Benchmark)public class AccessorBenchmark {    private static final Object[] EMPTY_ARGS = new Object[0];    private POJO source;    private Method method;    private MethodHandle methodHandle;    private MethodHandle methodHandleModifiedReturnType;    @Setup    public void setup() throws ReflectiveOperationException {        source = new POJO();        method = source.getClass().getDeclaredMethod("getNumber");        methodHandle = MethodHandles.lookup().unreflect(method);        methodHandleModifiedReturnType = methodHandle.asType(methodHandle.type().changeReturnType(Number.class));    }    @Benchmark    public Number reflection() throws Throwable {        return (Number) method.invoke(source, EMPTY_ARGS);    }    @Benchmark    public Number methodHandle() throws Throwable {        return (Number) methodHandle.invoke(source);    }    @Benchmark    public Number methodHandleInvokeExact() throws Throwable {        return  (Number) methodHandleModifiedReturnType.invokeExact(source);    }    public class POJO {        private final AtomicInteger counter = new AtomicInteger();        public AtomicInteger getNumber() {            return counter;        }    }}

The following result is returned with Java 17:

Benchmark                                     Mode   Cnt   Score    Error   UnitsAccessorBenchmark.methodHandle                avgt  1000   2.856 ±  0.004   ns/opAccessorBenchmark.methodHandleInvokeExact     avgt  1000   2.359 ±  0.003   ns/opAccessorBenchmark.reflection                  avgt  1000   2.017 ±  0.002   ns/op

Any ideas?


Viewing all articles
Browse latest Browse all 36

Trending Articles