Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java int与long的迭代速度_Java_Performance_Optimization_Jit - Fatal编程技术网

Java int与long的迭代速度

Java int与long的迭代速度,java,performance,optimization,jit,Java,Performance,Optimization,Jit,我有以下两个项目: long startTime = System.currentTimeMillis(); for (int i = 0; i < N; i++); long endTime = System.currentTimeMillis(); System.out.println("Elapsed time: " + (endTime - startTime) + " msecs"); 我使用的是Windows XP Professional x64版Service Pack

我有以下两个项目:

long startTime = System.currentTimeMillis();
for (int i = 0; i < N; i++);
long endTime = System.currentTimeMillis();
System.out.println("Elapsed time: " + (endTime - startTime) + " msecs");
我使用的是Windows XP Professional x64版Service Pack 2,具有2.40GHz的Intel Core2四CPU


免责声明


我知道微基准在生产中没有用处。我还知道
System.currentTimeMillis()
并不像它的名字所暗示的那样准确。这只是我在闲逛时注意到的,我只是好奇为什么会发生这种情况;仅此而已。

您可能正在使用32位JVM。对于64位JVM,结果可能会有所不同。在32位JVM中,int可以映射到本机32位整数,并通过单个操作递增。同样的情况不会持续很长时间,这将需要更多的操作来增加


有关int和long大小的讨论,请参见此部分。

这是一个有趣的问题,但老实说,我不相信在这里考虑Hotspot的行为会产生有用的信息。在一般情况下,您得到的任何答案都是不可转移的(因为我们正在研究Hotspot在特定情况下的优化),因此它们将帮助您理解为什么一个no op比另一个更快,但它们不会帮助您编写更快的“真实”程序

围绕这类事情编写非常容易误导人的微观基准也非常容易——请参阅一些常见的陷阱,如何避免它们,以及一些关于您所做工作的一般性评论


所以这确实是一个“无可奉告”的回答,但我认为这是唯一有效的回答。编译时简单的无操作循环不需要很快,因此编译器在某些情况下没有优化为快速。

我的猜测——这只是猜测——是这样的:

JVM得出结论,第一个循环实际上什么也不做,因此它完全删除了它。没有变量从for循环中“转义”

在第二种情况下,循环也不执行任何操作。但可能是确定循环什么都不做的JVM代码有一个“if(type of i)==int”子句。在这种情况下,删除“不做任何事情”循环的优化只适用于int


删除代码的优化必须确保没有副作用。JVM程序员似乎在谨慎方面犯了错误。

像这样的微观基准测试没有多大意义,因为结果在很大程度上取决于Hotspot JIT的内部工作

另外,请注意,使用
system.currentTimeMillis()
获得的系统时钟值并非在所有操作系统上都具有1毫秒的分辨率。你不能用它来非常准确地为持续时间很短的事件计时


看看这篇文章,这就解释了为什么用Java进行微基准测试不像大多数人认为的那么容易:

好的观点。但是,我使用的是64位JVM。我会更新这个问题。发布操作系统和一些关于硬件配置(主要是CPU)的细节也会很有用。当然你是对的。我问这个问题的原因纯粹是对我在闲逛时注意到的东西的好奇;我不打算在真正的程序中这样做。:)我完全同意这里的@Andrzej,但如果真的只是出于好奇,您可以使用PrintAssembly插件来真正查看生成的代码:如果使用-Xint标志运行会发生什么?这会阻止热点编译,因此您将获得更好的比较。@史蒂文:但是使用
-Xint
时,结果对于任何类似实际使用的东西来说都没有什么意义。如果有人想运行PrintAssembly并发布结果,我很好奇PrintAssembly会显示什么。。。
long startTime = System.currentTimeMillis();
for (long i = 0; i < N; i++);
long endTime = System.currentTimeMillis();
System.out.println("Elapsed time: " + (endTime - startTime) + " msecs");
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)