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

Java poor performance with non-static `VarHandle`

$
0
0

I was investigating if replacing a java.lang.reflect.Field.get call with a VarHandle would improve performance, but instead it got slower.

From benchmarking, I can see that when the VarHandle is static, it outperforms Field.get (obviously) - but when it's not, it's about twice as slow.

For my use-case, it needs to generic across unknown classes - so not static - e.g. think about serialization.

Is there an alternative way to outperform Field.get?

Benchmark:

import org.openjdk.jmh.annotations.*;import java.lang.invoke.*;import java.lang.reflect.Field;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 ReflectiveFieldAccessBenchmark {    static {        try {            field = ReflectiveFieldAccessBenchmark.class.getDeclaredField("count");        } catch (final ReflectiveOperationException e) {            throw new ExceptionInInitializerError(e);        }    }    private static final Field field;    private static final VarHandle staticVarHandle = getVarHandle();    private final VarHandle nonStaticVarHandle = getVarHandle();    private final Number count = new AtomicInteger(Integer.MAX_VALUE);    private static VarHandle getVarHandle() {        try {            return MethodHandles.lookup().unreflectVarHandle(field);        } catch (final ReflectiveOperationException e) {            throw new RuntimeException(e);        }    }    @Benchmark    public Object reflection() throws Exception {        return field.get(this);    }    @Benchmark    public Object staticVarHandle() throws Exception {        return staticVarHandle.get(this);    }    @Benchmark    public Object nonStaticVarHandle() throws Exception {        return nonStaticVarHandle.get(this);    }}

Output:

Benchmark                                                                         Mode   Cnt   Score    Error   UnitsReflectiveFieldAccessBenchmark.nonStaticVarHandle                                 avgt  1000   3.485 ±  0.005   ns/opReflectiveFieldAccessBenchmark.reflection                                         avgt  1000   2.027 ±  0.002   ns/opReflectiveFieldAccessBenchmark.staticVarHandle                                    avgt  1000   0.433 ±  0.002   ns/op

Viewing all articles
Browse latest Browse all 36

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>