我正在研究用
java.lang.reflect.Field.get
替换 VarHandle
调用是否会提高性能,但反而变慢了。
从基准测试中,我可以看到,当
VarHandle
为 static
时,它的性能优于 Field.get
(显然) - 但当不是时,它的速度大约慢两倍。
对于我的用例,它需要跨未知类通用 - 所以不是静态的 - 例如考虑序列化。
是否有其他方法可以超越
Field.get
?
基准:
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);
}
}
输出:
Benchmark Mode Cnt Score Error Units
ReflectiveFieldAccessBenchmark.nonStaticVarHandle avgt 1000 3.485 ± 0.005 ns/op
ReflectiveFieldAccessBenchmark.reflection avgt 1000 2.027 ± 0.002 ns/op
ReflectiveFieldAccessBenchmark.staticVarHandle avgt 1000 0.433 ± 0.002 ns/op