我在基准测试中注意到,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
答案 0 :(得分:6)
尝试反编译这两种情况:
static void a(double d0) {
d0 *= d0;
}
static void b(double d0) {
d0 = d0 * d0;
}
反编译为:
static void a(double);
Code:
0: dload_0
1: dload_0
2: dmul
3: dstore_0
4: return
static void b(double);
Code:
0: dload_0
1: dload_0
2: dmul
3: dstore_0
4: return
即。它们在字节码级别上是相同的,因此不存在内在的性能差异。此代码之外的因素会影响运行时间。
答案 1 :(得分:3)
a *= b;
生成与a = a * b;
完全相同的字节码。这意味着您的性能测试存在问题。
同样适用于+
,-
,/
等。