Java:Getter和Setter比直接访问更快?

耶先生:

在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百万次调用

我没有在微基准测试中进行测试,而是在光线跟踪器中进行了测试。我测试代码的方式:

  • 我用第一个代码启动了程序并进行了设置。光线跟踪器尚未运行。
  • 我启动了探查器,并在初始化完成后等待了一段时间。
  • 我启动了光线追踪器。
  • 当VisualVM显示足够的调用时,我停止了探查器,然后稍等片刻。
  • 我关闭了射线追踪程序。
  • 我将第二个代码替换为第一个代码,并在编译后重复上述步骤。

对于这两个代码,我至少运行了20,000,000次调用。我关闭了不需要的任何程序。我将CPU设置为性能,因此CPU时钟为最大。每时每刻。
第二个代码怎么可能快6%?

耶先生:

谢谢大家帮助我回答这个问题。最后,我找到了答案。

首先,Bohemian是正确的:通过PrintAssembly,我检查了生成的汇编代码相同的假设。是的,尽管字节码不同,但是生成的代码是相同的。
所以masterxilo是正确的:探查器必须是罪魁祸首。但是masterxilo对时序栅栏和更多仪器代码的猜测是不正确的。最后两个代码是相同的。

因此,仍然存在一个问题:第二个代码在探查器中怎么可能看起来快6%?

答案在于VisualVM的测量方式:开始分析之前,需要校准数据。这用于消除由探查器引起的开销时间。
尽管校准数据正确,但最终的测量结果却不正确。VisualVM在字节码中看到方法调用。但它看不到JIT编译器在优化时会删除这些调用。
因此,它消除了不存在的开销时间。这就是差异出现的方式。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章