在下面的代码中,很明显 baa 总是 false。热点编译器会发现这一点并删除 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()。所以我感兴趣的是方法调用本身是否被优化了。
回答我自己的问题...
我使用计时来测量热点何时完全摆脱代码。即,如果循环中的代码不再增加循环执行时间,则其已被编译出来。
在我对 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个时钟周期
因此,即使是热点编译的代码也不会影响周围代码的优化。