我正在进行一些测试,以了解使用 getter/setter 和直接字段访问之间的速度差异。我编写了一个简单的基准测试应用程序,如下所示:
public class FieldTest {
private int value = 0;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
public static void doTest(int num) {
FieldTest f = new FieldTest();
// test direct field access
long start1 = System.nanoTime();
for (int i = 0; i < num; i++) {
f.value = f.value + 1;
}
f.value = 0;
long diff1 = System.nanoTime() - start1;
// test method field access
long start2 = System.nanoTime();
for (int i = 0; i < num; i++) {
f.setValue(f.getValue() + 1);
}
f.setValue(0);
long diff2 = System.nanoTime() - start2;
// print results
System.out.printf("Field Access: %d ns\n", diff1);
System.out.printf("Method Access: %d ns\n", diff2);
System.out.println();
}
public static void main(String[] args) throws InterruptedException {
int num = 2147483647;
// wait for the VM to warm up
Thread.sleep(1000);
for (int i = 0; i < 10; i++) {
doTest(num);
}
}
}
每当我运行它时,我都会得到一致的结果,例如:http://pastebin.com/hcAtjVCL http://pastebin.com/hcAtjVCL
我想知道是否有人可以向我解释为什么字段访问似乎比 getter/setter 方法访问慢,以及为什么最后 8 次迭代执行得非常快。
Edit: 考虑到assylias
and Stephen C
评论,我已将代码更改为http://pastebin.com/Vzb8hGdc http://pastebin.com/Vzb8hGdc我得到的结果略有不同:http://pastebin.com/wxiDdRix http://pastebin.com/wxiDdRix .
解释是你的基准被打破了。
第一次迭代是使用解释器完成的。
Field Access: 1528500478 ns
Method Access: 1521365905 ns
第二次迭代由解释器开始,然后我们转向运行 JIT 编译的代码。
Field Access: 1550385619 ns
Method Access: 47761359 ns
其余迭代均使用 JIT 编译代码完成。
Field Access: 68 ns
Method Access: 33 ns
etcetera
他们的原因是难以置信地快的是 JIT 编译器优化了循环。它检测到他们没有为计算贡献任何有用的东西。 (尚不清楚为什么第一个数字似乎始终比第二个数字快,但我怀疑优化的代码是否以任何有意义的方式测量字段与方法访问。)
Re the UPDATED代码/结果:很明显,JIT 编译器仍在优化循环。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)