我在Linux上网本上测试了使用VisualVM 1.3.7 编写的Java ray跟踪器的性能。我用分析器进行了测量。
为了好玩,我测试了使用getter和setter与直接访问字段之间是否有区别。getter和setter是标准代码,没有添加。
我没想到会有任何差异。但是直接访问代码的速度较慢。
这是我在Vector3D中测试的示例:
public float dot(Vector3D other) {
return x * other.x + y * other.y + z * other.z;
}
时间:1542毫秒/ 1百万次调用
public float dot(Vector3D other) {
return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ();
}
时间:1453毫秒/ 1百万次调用
我没有在微基准测试中进行测试,而是在光线跟踪器中进行了测试。我测试代码的方式:
对于这两个代码,我至少运行了20,000,000次调用。我关闭了不需要的任何程序。我将CPU设置为性能,因此CPU时钟为最大。每时每刻。
第二个代码怎么可能快6%?
谢谢大家帮助我回答这个问题。最后,我找到了答案。
首先,Bohemian是正确的:通过PrintAssembly,我检查了生成的汇编代码相同的假设。是的,尽管字节码不同,但是生成的代码是相同的。
所以masterxilo是正确的:探查器必须是罪魁祸首。但是masterxilo对时序栅栏和更多仪器代码的猜测是不正确的。最后两个代码是相同的。
因此,仍然存在一个问题:第二个代码在探查器中怎么可能看起来快6%?
答案在于VisualVM的测量方式:开始分析之前,需要校准数据。这用于消除由探查器引起的开销时间。
尽管校准数据正确,但最终的测量结果却不正确。VisualVM在字节码中看到方法调用。但它看不到JIT编译器在优化时会删除这些调用。
因此,它消除了不存在的开销时间。这就是差异出现的方式。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句