Java:Getter和setter比直接访问更快? [英] Java: Getter and setter faster than direct access?

查看:112
本文介绍了Java:Getter和setter比直接访问更快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux上网本上使用 VisualVM 1.3.7测试了我正在编写的Java光线跟踪器的性能。我使用分析器进行测量。

为了好玩,我测试了如果使用getter和setter以及直接访问字段之间存在差异。 getter和setter是标准代码,没有添加。

I tested the performance of a Java ray tracer I'm writing on with VisualVM 1.3.7 on my Linux Netbook. I measured with the profiler.
For fun I tested if there's a difference between using getters and setters and accessing the fields directly. The getters and setters are standard code with no addition.

我没想到会有任何差异。但直接访问代码的速度较慢。

I didn't expected any differences. But the directly accessing code was slower.

这是我在Vector3D中测试的样本:

Here's the sample I tested in Vector3D:

public float dot(Vector3D other) {
    return x * other.x + y * other.y + z * other.z;
}

时间:1542 ms / 1,000,000次调用

Time: 1542 ms / 1,000,000 invocations

public float dot(Vector3D other) {
    return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ();
}

时间:1453 ms / 1,000,000次调用

Time: 1453 ms / 1,000,000 invocations

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

I didn't test it in a micro-benchmark, but in the ray tracer. The way I tested the code:


  • 我用第一个代码启动程序并进行设置。光线跟踪器尚未运行。

  • 我启动了探查器并在初始化完成后等待了一段时间。

  • 我启动了光线跟踪器。

  • 当VisualVM显示足够的调用时,我停止了探查器并等了一会儿。

  • 我关闭了光线跟踪器程序。

  • 我用第二个代码替换第一个代码并在编译后重复上述步骤。

  • I started the program with the first code and set it up. The ray tracer isn't running yet.
  • I started the profiler and waited a while after initialization was done.
  • I started a ray tracer.
  • When VisualVM showed enough invocations, I stopped the profiler and waited a bit.
  • I closed the ray tracer program.
  • I replaced the first code with the second and repeated the steps above after compiling.

我至少运行了20,000,000两个代码的调用。我关闭了任何我不需要的程序。
我设置CPU的性能,所以我的CPU时钟是最大的。所有的时间。

第二个代码怎么可能快6%?

I did at least run 20,000,000 invocations for both codes. I closed any program I didn't need. I set my CPU on performance, so my CPU clock was on max. all the time.
How is it possible that the second code is 6% faster?

推荐答案

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

Thank you all for helping me answering this question. In the end, I found the answer.

首先,波希米亚是正确的:使用 PrintAssembly 我检查了假设生成的汇编代码是相同的。是的,虽然字节码不同,但生成的代码是相同的。

所以 masterxilo是对的:探查者必须是罪魁祸首。但是masterxilo对时序栅栏和更多仪器代码的猜测并不属实;两个代码最终都是相同的。

First, Bohemian is right: With PrintAssembly I checked the assumption that the generated assembly codes are identical. And yes, although the bytecodes are different, the generated codes are identical.
So masterxilo is right: The profiler have to be the culprit. But masterxilo's guess about timing fences and more instrumentation code can't be true; both codes are identical in the end.

所以还有一个问题:第二个代码在Profiler中的速度有多快6%?

So there's still the question: How is it possible that the second code seems to be 6% faster in the profiler?

答案在于VisualVM的测量方式:之前如果要开始分析,则需要校准数据。这用于消除分析器引起的开销时间。

虽然校准数据是正确的,但测量的最终计算不是。 VisualVM在字节码中看到方法调用。但它没有看到JIT编译器在优化时删除了这些调用。

因此它消除了不存在的开销时间。这就是差异的出现。

The answer lies in the way how VisualVM measures: Before you start profiling, you need calibration data. This is used for removing the overhead time caused by the profiler.
Although the calibration data is correct, the final calculation of the measurement is not. VisualVM sees the method invocations in the bytecode. But it doesn't see that the JIT compiler removes these invocations while optimizing.
So it removes non-existing overhead time. And that's how the difference appears.

这篇关于Java:Getter和setter比直接访问更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆