java - JIT 编译器可以内联 Java 8 默认接口(interface)方法吗?

标签 java optimization jvm jit jvm-hotspot

我正在分析 HotSpot 日志以获取我在 JITWatch 中为一段代码运行的基准,并注意到许多方法调用由于“无静态绑定(bind)”而没有被内联。这些似乎只发生在对默认接口(interface)方法的调用中。
我的问题是默认接口(interface)方法会阻止 JIT 编译器内联它们的调用吗?

interface A {
    default double a() {
        return Math.random();
    }
}

interface B extends A {
    default double b() {
        return a();
    }
}

class C implements B {
    public double c() {
        double c = 0;
        for (int i = 0; i < 1_000_000; ++i) {
            c += b();
        }
        return c;
    }

    public static void main(String[] args) {
        System.out.println(new C().c());
    }
}

在 JITWatch 中进一步检查后,似乎此问题与调用其他默认接口(interface)方法的默认接口(interface)方法有关。鉴于“无静态绑定(bind)”消息,这将更有意义。

最佳答案

Eugene 的示例表明可以内联默认方法。
事实上,我认为内联的标准应该与任何其他非静态方法相同。

  • 要内联的代码大小必须小于可调阈值。
  • 该方法不得被类或接口(interface)的任何(当前加载的)子类中的方法覆盖。

  • 在您的示例中,我认为内联应该是可能的,假设这是示例中涉及的所有代码。
    但是,此处使用的特定 JIT 中的/可能存在其他限制。例如,一个调用另一个默认方法的默认方法可能是一种非常罕见的极端情况,以至于它被认为不值得支持。另一种可能的解释是 C1 编译器不进行深度单态调度分析/优化。
    另一方面,这可能是过早的优化......除非您的性能分析已经确定了代码中的特定热点,其中内联可能会产生重大影响。通常,最好的策略是将其留给编译器。如果您对代码进行微优化以为给定的 Java 版本提供最佳性能,那么当您更改为较新的版本时,您很有可能需要重做工作。

    关于java - JIT 编译器可以内联 Java 8 默认接口(interface)方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65473680/

    相关文章:

    Java Spring - 作为属性值的注释参数

    iphone - 如何衡量在 iOS 中花费的网络时间的分割?

    java - 如何修复 java.lang.UnsupportedClassVersionError : Unsupported major. 次要版本

    java - 在 Android 中映射空间数据

    java - 下面的作业有什么作用?

    C - 有一个简单的循环来进行算术计算;探查器显示这是一个瓶颈。如何加快速度?

    mysql - 如何优化此查询?运行需要 3 分钟

    java - JVM Clustering如何进行负载均衡。

    java - JVM 是否限制 Executor 可以运行的线程数量?

    java - 通过传递 IV 进行 AES 256 加密