为什么在JDK 1.8中,MethodHandle比反射(Reflection)要慢?

huangapple 未分类评论53阅读模式
英文:

Why MethodHandle is slow than Reflection in JDK 1.8?

问题

我有两个使用 JMH 进行性能测试的测试案例。代码非常简单,其中一个使用了 Java 反射,另一个使用了 MethodHandle(在 JDK 1.7 中引入)。顺便说一下,isEmptyMethod 和 MH_isEmpty 被声明为静态 final,像这样:

    private static final MethodHandle MH_isEmpty;
    private static final Method isEmptyMethod;

    static {
        try {
            MH_isEmpty = MethodHandles.publicLookup().findVirtual(String.class, "isEmpty", MethodType.methodType(boolean.class));
            isEmptyMethod = String.class.getDeclaredMethod("isEmpty");
        } catch (Exception ex) {
            throw new UnsupportedOperationException();
        }
    }

Java 反射:

    @BenchmarkMode(Mode.Throughput)
    public void testReflectionGetIsEmpty() throws Exception {
        isEmptyMethod.setAccessible(false);
        final Object result = isEmptyMethod.invoke("SmartLee");
    }

MethodHandle:

    @Benchmark
    @BenchmarkMode(Mode.Throughput)
    public void testFindVirtual() throws Throwable {
        final MethodHandle isEmpty = MH_isEmpty.bindTo("SmartLee");
        isEmpty.invoke();
    }

以下是性能测试结果:
[性能测试结果链接][1]

根据[JDK文档][2],为什么 MethodHandle 不比 Java 反射更快呢?
上面的代码有什么问题吗?

  [1]: https://i.stack.imgur.com/Mwt6e.png
  [2]: https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandle.html

注意:以上是您提供的内容的翻译。如有其他需要或问题,请随时提问。

英文:

I have two performance tests using JMH. The code is very easy,one is using Java Reflection,Another is using MethodHandle(Introduced in JDK1.7),By The way,isEmptyMethod and MH_isEmpty is declared as static final,like this:

private static final MethodHandle MH_isEmpty;
private static final Method isEmptyMethod;

static {
    try {
        MH_isEmpty = MethodHandles.publicLookup().findVirtual(String.class, "isEmpty", MethodType.methodType(boolean.class));
        isEmptyMethod = String.class.getDeclaredMethod("isEmpty");
    } catch (Exception ex) {
        throw new UnsupportedOperationException();
    }
}

` Java Reflection:

@BenchmarkMode(Mode.Throughput)
public void testReflectionGetIsEmpty() throws Exception {
    isEmptyMethod.setAccessible(false);
    final Object result = isEmptyMethod.invoke("SmartLee");
}

`
MethodHandle:

@Benchmark
@BenchmarkMode(Mode.Throughput)
public void testFindVirtual() throws Throwable {
    final MethodHandle isEmpty = MH_isEmpty.bindTo("SmartLee");
    isEmpty.invoke();
}

Beblow is the performance results:
performance results

According to JDK docs.Why MethodHandle is not faster than java reflection?
What's wrong with above code?

huangapple
  • 本文由 发表于 2020年7月24日 11:47:36
  • 转载请务必保留本文链接:https://java.coder-hub.com/63066493.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定