我正在玩一些代码来计算计算一些 Java 代码所需的时间,以了解某些 Java 功能的效率或低效率。这样做我现在陷入了一些我无法解释的非常奇怪的效果。也许你们中有人可以帮助我理解它。
public class PerformanceCheck {
public static void main(String[] args) {
List<PerformanceCheck> removeList = new LinkedList<PerformanceCheck>();
int maxTimes = 1000000000;
for (int i=0;i<10;i++) {
long time = System.currentTimeMillis();
for (int times=0;times<maxTimes;times++) {
// PERFORMANCE CHECK BLOCK START
if (removeList.size() > 0) {
testFunc(3);
}
// PERFORMANCE CHECK BLOCK END
}
long timeNow = System.currentTimeMillis();
System.out.println("time: " + (timeNow - time));
}
}
private static boolean testFunc(int test) {
return 5 > test;
}
}
开始这个会导致相对较长的计算时间(记住 removeList 是空的,所以甚至不会调用 testFunc):
time: 2328
time: 2223
...
虽然将 removeList.size() > 0 和 testFunc(3) 的任何组合替换为其他任何东西都会有更好的结果。例如:
...
if (removeList.size() == 0) {
testFunc(3);
}
...
结果(每次调用 testFunc):
time: 8
time: 7
time: 0
time: 0
即使调用彼此独立的两个函数也会导致更短的计算时间:
...
if (removeList.size() == 0);
testFunc(3);
...
结果:
time: 6
time: 5
time: 0
time: 0
...
在我最初的例子中只有这个特定的组合需要这么长时间。这让我很恼火,我真的很想了解它。它有什么特别之处?
谢谢。
添加:
改变第一个例子中的 testFunc()
if (removeList.size() > 0) {
testFunc(times);
}
其他的东西,比如
private static int testFunc2(int test) {
return 5*test;
}
将导致再次变快。
最佳答案
这真是令人惊讶。生成的字节码是相同的,除了条件,即 ifle
和 ifne
。
如果使用 -Xint
关闭 JIT,结果会更加合理。第二个版本慢 2 倍。所以这跟JIT优化有什么关系。
我假设它可以优化第二种情况下的检查,但不能优化第一种情况(无论出于何种原因)。尽管这意味着它完成了函数的工作,但缺少条件会使事情变得更快。它避免了流水线停顿等等。
关于Java效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8931754/