0

在尝试比较数据类型“int”和“long”的性能时,我遇到了这个奇怪的问题,基本上我有两个单元测试:

@Test
public void testLongOperationPerformance(){
    StopWatch sw = new StopWatch();
    sw.start();
    long count = 0l;
    for(int i = 0; i < Integer.MAX_VALUE; i ++){
        count++;
    }
    sw.stop();
    System.out.println(count);
    System.out.println(sw.elaspedTimeInMilliSeconds());
}

@Test
public void testIntegerOperationPerformance(){
    StopWatch sw = new StopWatch();
    sw.start();
    int count = 0;
    for(int i = 0; i < Integer.MAX_VALUE; i ++){
        count++;
    }
    sw.stop();
    System.out.println(count);
    System.out.println(sw.elaspedTimeInMilliSeconds());
}

这两个单元测试做同样的事情,不同的是一个使用 int 作为 counter 的数据类型,另一个使用 long 作为那个。结果:

jdk6u32 (64 bit):
test with long
2147483635
96
test with int
2147483647
2

jdk7 (64 bit)
test with long
2147483647
1599
test with int
2147483647
1632

我注意到:

  1. 在 jdk6u32 中,使用 int 进行测试比使用 long 进行测试要快得多
  2. 在 jdk6u32 中,int 测试和 long 测试的测试结果不同
  3. 在 jdk7 中,两个测试的速度差不多,而且都比 jdk6u32 慢得多
  4. 在 jdk7 中,两个测试都得到了相同的结果

谁能解释为什么会这样?

4

1 回答 1

6

Java JIT 特别擅长消除不做任何事情的代码。在您的示例中,循环

long count = 0l;
for(int i = 0; i < Integer.MAX_VALUE; i ++){
    count++;
}

可以替换为

long count = 0l;
count += Integer.MAX_VALUE * 1;

您正在计时的是检测和移除循环需要多长时间。这个时间可能取决于它之前所做的事情,所以我建议以不同的顺序测试循环,看看是否会改变结果。

在 Java 6 和 7 中,许多循环优化被错误地优化。

例如,对于某些更新,这个无限循环并不总是无限的

for(int i=0; i < Integer.MAX_VALUE; i += 2)

因此,某些更新会根据它们是否适用于该版本而开启或关闭不同的优化。我建议尝试最新版本的 Java 7,看看它是否有所作为。

于 2012-08-30T05:45:41.577 回答