我在Surface Pro 2平板电脑上运行带有Java 7更新45 x64(没有安装32位Java)的Windows 8.1 x64.
当i的类型为long时,下面的代码需要1688ms,当i是int时,代码需要109ms.为什么在具有64位JVM的64位平台上,long(64位类型)比int慢一个数量级?
我唯一的猜测是,CPU需要更长的时间来添加64位整数而不是32位整数,但这似乎不太可能.我怀疑Haswell不使用纹波进位加法器.
我在Eclipse Kepler SR1中运行它,顺便说一句.
public class Main {
private static long i = Integer.MAX_VALUE;
public static void main(String[] args) {
System.out.println("Starting the loop");
long startTime = System.currentTimeMillis();
while(!decrementAndCheck()){
}
long endTime = System.currentTimeMillis();
System.out.println("Finished the loop in " + (endTime - startTime) + "ms");
}
private static boolean decrementAndCheck() {
return --i < 0;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:以下是VS 2013(下面),同一系统编译的等效C++代码的结果. 长:72265ms int:74656ms 这些结果是在调试32位模式下.
在64位发布模式下: 长:875ms long long:906ms int:1047ms
这表明我观察到的结果是JVM优化怪异而不是CPU限制.
#include "stdafx.h"
#include "iostream"
#include …Run Code Online (Sandbox Code Playgroud) 听说Java支持“Loop Unswitching”,所以就在JMH上简单测试了一下。
我认为在 JIT 之后它们会完全相同。为什么是这样?
private final int TIMES = 1_000_000;
private boolean bool;
private Random r = new Random(93);
@Setup(Level.Invocation)
public void fresh() {
bool = r.nextBoolean();
}
@Benchmark
public void test1(Blackhole bh) {
for (int i = 0; i < TIMES; i++) {
if (bool) {
bh.consume(1);
} else {
bh.consume(2);
}
}
}
@Benchmark
public void test2(Blackhole bh) {
if (bool) {
for (int i = 0; i < TIMES; i++) {
bh.consume(1);
}
} else { …Run Code Online (Sandbox Code Playgroud)