jqn*_*qno 8 java optimization performance jit
我有以下两个程序:
long startTime = System.currentTimeMillis();
for (int i = 0; i < N; i++);
long endTime = System.currentTimeMillis();
System.out.println("Elapsed time: " + (endTime - startTime) + " msecs");
Run Code Online (Sandbox Code Playgroud)
和
long startTime = System.currentTimeMillis();
for (long i = 0; i < N; i++);
long endTime = System.currentTimeMillis();
System.out.println("Elapsed time: " + (endTime - startTime) + " msecs");
Run Code Online (Sandbox Code Playgroud)
注意:唯一的区别是循环变量(int和long)的类型.
当我运行它时,第一个程序始终打印0到16毫秒,无论值是什么N.第二个需要更长的时间.因为N == Integer.MAX_VALUE,它在我的机器上运行大约1800毫秒.运行时间似乎或多或少是线性的N.
那么为什么呢?
我想JIT编译器会优化int循环到死.并且有充分的理由,因为显然它什么都不做.但是为什么它也不是这样做的long呢?
一位同事认为我们可能正在测量JIT编译器在long循环中的工作,但由于运行时似乎是线性的N,所以情况可能并非如此.
我正在使用JDK 1.6.0更新17:
C:\>java -version
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)
Run Code Online (Sandbox Code Playgroud)
我使用的是Windows XP Professional x64 Edition,Service Pack 2,配备2.40GHz的Intel Core2 Quad CPU.
免责声明
我知道微基准测试在生产中没用.我也知道这System.currentTimeMillis()不像它的名字那么准确.这只是我在鬼混时注意到的事情,我只是好奇为什么会发生这种情况; 而已.
这是一个有趣的问题,但说实话,我不相信考虑Hotspot在这里的行为会产生有用的信息.你得到的任何答案都不会在一般情况下转移(因为我们正在研究Hotspot在某种特定情况下执行的优化),所以它们会帮助你理解为什么一个no-op比另一个更快,但他们不会帮助你写更快的"真实"程序.
在这类事情上编写非常容易误导性的微基准测试也非常容易 - 请参阅这篇IBM DW文章,了解一些常见的陷阱,如何避免它们以及对您正在做的事情的一些一般性评论.
所以这真的是一个"无评论"的答案,但我认为这是唯一有效的答案.编译时平凡无操作循环并不需要要快,所以编译器不优化要快一些的这些条件.