0

在下面的代码中,很明显 baa 总是错误的。热点编译器会发现这一点并删除 isBaa() 方法调用和包含的代码吗?

public class Foo() {
    public final boolean baa = false;
    public isBaa() {
        return baa;
    }
}

像这样的用法

static final Foo foo = new Foo();

public m() {
    if (foo.isBaa()) {
        // code here...
    }
}

我想知道这段代码是否与添加相比

static final Foo foo = new Foo();
static final BAA = foo.isBaa();

并检查

if (BAA) ...

热点完成后对运行速度感兴趣。反正有没有真正看到热点编译的结果是什么?还是我们必须从正在使用的热点编译器的实现细节中推断出来。

用例是在对性能非常敏感的代码中通过最终变量支持 isDebugEnabled()。所以我对方法调用本身是否被优化感兴趣。

4

1 回答 1

0

回答我自己的问题...

我使用时间来衡量热点何时完全摆脱了代码。即,如果循环中的代码不再增加循环执行时间,则它被编译出来。

  • 静态最终布尔检查可以完全编译出来。
  • 静态方法调用可以编译出来。
  • 实例方法,即使标记为 final,也不是。

在我对 ibm jdk8 的测试中,什么都不做的最终方法调用花费了大约 6 个时钟周期。

IBM 的 Hotspot 文档暗示最终实例方法可以内联,但测试表明仍然存在成本。我想未来的虚拟机可能会进一步优化这一点。

在我的测试中,热点编译似乎也会影响循环在 CPU 内核之间的分布方式。

for(; i < Integer.MAX_VALUE ; i++)

神奇地在所有 4 个 CPU 上运行(平均时间为时钟周期的 1/4)

for(; i < Integer.MAX_VALUE ; i++) if (false) ...

平均需要 1 个时钟周期

因此,即使是热点编译为空的代码也会影响周围代码的优化。

于 2017-09-04T16:08:27.010 回答