【发布时间】:2016-09-02 13:18:10
【问题描述】:
我在基准测试中注意到,Java 中的算术复合运算符总是优于常规赋值:
d0 *= d0; //faster
//d0 = d0 * d0; //slower
d0 += d0; //faster
//d0 = d0 + d0; //slower
有人可以对上述观察发表评论并解释为什么会这样。我假设字节码级别的一些差异是导致加速的原因?提前谢谢你。
这是我的更全面的基准:
public long squaring() {
long t0 = System.currentTimeMillis();
double d0 = 0;
for (int k = 0; k < 100_000_000; k++){
//check bytecode for below to see why timing differs
d0 *= d0; //faster
//d0 = d0 * d0; //slower
}
long t1 = System.currentTimeMillis();
long took = (t1 - t0);
System.out.println("took: "+took + " ms");
System.out.println("result: " +d0);
return took;
}
@Test
public void testSquaring() {
int repetitions = 10;
long sum = 0;
for (int i = 0; i < repetitions; i++) {
sum += cut.squaring();
System.out.println("accumulated: "+ sum + "\n-------------------");
}
double avg = sum/repetitions;
System.out.println("average: "+avg);
}
结果如下:
took: 244 ms
result: 0.0
accumulated: 244
-------------------
took: 302 ms
result: 0.0
accumulated: 546
-------------------
took: 0 ms
result: 0.0
accumulated: 546
-------------------
took: 0 ms
result: 0.0
accumulated: 546
-------------------
took: 0 ms
result: 0.0
accumulated: 546
-------------------
took: 0 ms
result: 0.0
accumulated: 546
-------------------
took: 0 ms
result: 0.0
accumulated: 546
-------------------
took: 0 ms
result: 0.0
accumulated: 546
-------------------
took: 0 ms
result: 0.0
accumulated: 546
-------------------
took: 0 ms
result: 0.0
accumulated: 546
-------------------
average: 54.0
【问题讨论】:
-
注释掉的代码执行两次乘法,而不是一次。这真的是你要比较的吗?
-
你可以只看字节码来验证你的假设。
-
也就是说,你衡量这个的方式很有可能会产生误导 - 请参阅 stackoverflow.com/questions/504103/…。
-
那些似乎产生完全相同的字节码。我认为问题在于你的测试。
-
“字节码级别的一些差异”
javap -c YourClass向您显示字节码。
标签: java performance syntax