今天我在java中遇到了一个相当惊人的行为,or
慢于and
!
我甚至做了一个你可以在下面看到的测试用例。现在我想知道为什么会这样?
我做错了什么或者只是在我的电脑上发生了什么?
我没有看到任何理由or
应该比and
慢,特别是这个显着的差异。我想用其他一些语言测试这种现象,你对这个一般有什么想法吗?
public class TestClass {
public static void main(String[] args) {
long[] or = new long[10];
long[] and = new long[10];
long lStartTime, lEndTime, difference = 0;
for (int idx = 0; idx < 10; idx++) {
lStartTime = System.nanoTime();
for (int i= 0; i < 1000000000; i++) {
int j = i | i+1 ;
}
lEndTime = System.nanoTime();
difference = lEndTime - lStartTime;
System.out.println("Elapsed milliseconds: " + difference/1000000);
or[idx] = difference;
lStartTime = System.nanoTime();
for (int i= 0; i < 1000000000; i++) {
int j = i & i+1 ;
}
lEndTime = System.nanoTime();
difference = lEndTime - lStartTime;
System.out.println("Elapsed milliseconds: " + difference/1000000);
and[idx] = difference;
System.out.println("------------------------------------" );
}
long tmp = 0;
for (long l : or) {
tmp += l;
}
tmp /= 10;
System.out.println("Elapsed milliseconds for or: " + tmp/1000000);
tmp = 0;
for (long l : and) {
tmp += l;
}
tmp /= 10;
System.out.println("Elapsed milliseconds for and: " + tmp/1000000);
}
}
结果:
Elapsed milliseconds: 1600 Elapsed milliseconds: 1332 ------------------------------------ Elapsed milliseconds: 1609 Elapsed milliseconds: 1335 ------------------------------------ Elapsed milliseconds: 1609 Elapsed milliseconds: 1335 ------------------------------------ Elapsed milliseconds: 1542 Elapsed milliseconds: 1314 ------------------------------------ Elapsed milliseconds: 1705 Elapsed milliseconds: 1324 ------------------------------------ Elapsed milliseconds: 1559 Elapsed milliseconds: 1315 ------------------------------------ Elapsed milliseconds: 1526 Elapsed milliseconds: 1314 ------------------------------------ Elapsed milliseconds: 1568 Elapsed milliseconds: 1340 ------------------------------------ Elapsed milliseconds: 1551 Elapsed milliseconds: 1318 ------------------------------------ Elapsed milliseconds: 1574 Elapsed milliseconds: 1321 ------------------------------------ Elapsed milliseconds for or: 1584 Elapsed milliseconds for and: 1325
答案 0 :(得分:5)
Bit-Wise OR 不比Bit-Wise AND慢!
在代码中的时间测量代码段之间切换,您将获得相反的结果:
for (int idx = 0; idx < 10; idx++) {
lStartTime = System.nanoTime();
for (int i= 0; i < 1000000000; i++) {
int j = i & i+1 ;
}
lEndTime = System.nanoTime();
difference = lEndTime - lStartTime;
System.out.println("Elapsed milliseconds: " + difference/1000000);
and[idx] = difference;
lStartTime = System.nanoTime();
for (int i= 0; i < 1000000000; i++) {
int j = i | i+1 ;
}
lEndTime = System.nanoTime();
difference = lEndTime - lStartTime;
System.out.println("Elapsed milliseconds: " + difference/1000000);
or[idx] = difference;
System.out.println("------------------------------------");
}
我倾向于猜测JVM在第二个片段中应用了某种运行时优化。
答案 1 :(得分:4)
Writing correct micro benchmarks就像你所做的一样非常耗时且容易出错。我建议使用现有的库,例如而是Caliper。
这是在Caliper中完成的相应基准测试(编译时需要的最新git版本):
public class BitwiseOperatorPerformance {
@Benchmark
public int timeOr(int reps){
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy |= i+1;
}
return dummy;
}
@Benchmark
public int timeAnd(int reps){
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy &= i+1;
}
return dummy;
}
}
以下是测试结果:link
结果显示, AND和OR运算符的性能完全相同。