我正在尝试使用谓词。我试图实现在分布式系统中序列化问题的谓词。我写了一个简单的示例,其中测试函数只返回true。我正在测量开销,然后遇到了这个有趣的问题。在for循环中访问数组比直接访问慢10倍。
class Test {
public boolean test(Object o) { return true; }
}
long count = 1000000000l;
Test[] test = new Test[3];
test[0] = new Test();
test[1] = new Test();
test[2] = new Test();
long milliseconds = System.currentTimeMillis();
for(int i = 0; i < count; i++){
boolean result = true;
Object object = new Object();
for(int j = 0; j < test.length; j++){
result = result && test[j].test(object);
}
}
System.out.println((System.currentTimeMillis() - milliseconds));
然而,以下代码的速度几乎快了10倍。可能的原因是什么?
milliseconds = System.currentTimeMillis();
for(int i=0 ; i < count; i++) {
Object object = new Object();
boolean result = test[0].test(object) && test[1].test(object) && test[2].test(object);
}
System.out.println((System.currentTimeMillis() - milliseconds));
我的i5的基准测试结果。
使用for循环访问的时间为4567毫秒
直接访问的时间为297毫秒
!result && j < test.length
,并初始化boolean result = false
以使其有同样的短路机会。 - Crusha K. Roolfoo()
的方法中,将另一种方法放入名为bar()
的方法中,然后从您的main
方法中交替调用这些方法,可能会调用20次。对我来说,在几次调用之后,这些方法将花费完全相同的时间。(从java -server ...
开始可能有所帮助)。第一个方法可能会更复杂一些,这可能是JIT稍后启动的原因,但最终没有区别。 - Marco13result
变量都没有被使用,编译器基本上可以消除整个程序。而第一种方法中result
变量被读取和写入,但在第二种方法中只被写入,这可能是优化器更容易发现整个代码实际上是无用的另一个原因... - Marco13