Java 使用非静态 `VarHandle` 性能较差

问题描述 投票:0回答:1

我正在研究用

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
java performance reflection methodhandle varhandle
1个回答
0
投票

是否有其他方法可以超越 Field.get?

Lmbda图书馆

实施 ns/op
直接 0.32
反思 1.92
Lmbda 0.68
© www.soinside.com 2019 - 2024. All rights reserved.