下面的代码运行完全相同的计算 3 次(它做的不多:基本上是从 1 到 100m 的所有数字相加)。前两个块的运行速度比第三个快大约 10 倍。我已经运行了这个测试程序超过 10 次,结果显示的差异很小。
如果有的话,我希望第三个块运行得更快(JIT 编译),但典型的输出是:
35974537
36368455
296471550
有人可以解释发生了什么吗?(为了清楚起见,我不想在这里解决任何问题,只是想更好地了解发生了什么)
笔记:
- 程序期间不运行 GC(用 监控
-XX:+PrintGC
) - 使用 Oracle JDK 版本 1.6.0_30、1.7.0_02 和 1.7.0_05 测试
- 还使用以下参数进行了测试:
-XX:+PrintGC -Xms1000m -Xmx1000m -XX:NewSize=900m
=> 相同的结果 - 如果将块放入循环中,则所有运行都很快
- 如果将块提取到方法中,则所有运行都很快(方法是否被调用 3 次或循环调用没有区别)
public static void main(String... args) {
//three identical blocks
{
long start = System.nanoTime();
CountByOne c = new CountByOne();
int sum = 0;
for (int i = 0; i < 100000000; i++) {
sum += c.getNext();
}
if (sum != c.getSum()) throw new IllegalStateException(); //use sum
long end = System.nanoTime();
System.out.println((end - start));
}
{
long start = System.nanoTime();
CountByOne c = new CountByOne();
int sum = 0;
for (int i = 0; i < 100000000; i++) {
sum += c.getNext();
}
if (sum != c.getSum()) throw new IllegalStateException(); //use sum
long end = System.nanoTime();
System.out.println((end - start));
}
{
long start = System.nanoTime();
CountByOne c = new CountByOne();
int sum = 0;
for (int i = 0; i < 100000000; i++) {
sum += c.getNext();
}
if (sum != c.getSum()) throw new IllegalStateException(); //use sum
long end = System.nanoTime();
System.out.println((end - start));
}
}
public static class CountByOne {
private int i = 0;
private int sum = 0;
public int getSum() {
return sum;
}
public int getNext() {
i += 1;
sum += i;
return i;
}
}