[英]Why JVM does't execute the code?
我正在测试分支预测,如下代码:
//first loop
int sortedSum = 0;
long sortedStartTime = System.nanoTime();
for (int i = 0; i < sortedArray.length; i++) {
if (sortedArray[i] < 0) {
sortedSum += sortedArray[i];
}
}
long sortedTime = System.nanoTime() - sortedStartTime;
//second loop
int randomSum = 0;
long randomStartTime = System.nanoTime();
for (int i = 0; i < randomArray.length; i++) {
if (randomArray[i] < 0) {
randomSum += randomArray[i];
}
}
long randomTime = System.nanoTime() - randomStartTime;
System.out.println("random time: " + randomTime);
System.out.println("sorted time: " + sortedTime);
简单打印每个for循环的时间。
请注意, sortedSum
和randomSum
在循环中分配,但从未访问过。
这里我们不讨论分支预测,而是输出结果。 输出为:
random time: 32
sorted time: 1595942
然后,将第二个for循环放在第一个循环之前(第一个randomArray循环,第二个sortedArray)。 输出为:
random time: 1541919
sorted time: 40
看来JVM没有执行第二个循环。 我反编译类文件,反编译器不会删除任何内容。
为什么? 以及为什么JVM会执行第一个循环?
PS环境是:
Ubuntu 12.04 LTS
java version "1.7.0_11"
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)
当您的运行时代码足够多时,它将触发整个方法的优化(在后台)
这意味着,如果您有一个循环进行10K次以上且不执行任何操作,则实际上是在计时检测该循环不执行任何操作并替换它所花费的时间。
在第二个循环的情况下,无论哪种情况,该方法都已被优化。
我建议您有一个运行此测试3次的外部循环,您应该明白我的意思。
它可以放弃循环的原因是:
calculateSum
我想这:
我们在这里谈论即时编译。 编译器在开始执行后仅优化了一段时间。 我猜想他会优化一切。 只要JIT编译器尚未启动,就执行第一个循环。
我认为这与Java没有关系,但是与CPU,内存和缓存有关:
首先, System.nanoTime()
应用位于内存中,执行代码处于CPU缓存级别1(以CPU的速度)。 当程序开始执行时,CPU将开始以1或2级现金的形式将内存块放在前面,因此顺序读/写的速度将会提高。
尝试使用大小比CPU 3级缓存大得多的数组,例如10MB和随机索引,即按随机顺序准备索引数组。 这将消除CPU兑现的影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.