java - jdk6和jdk7相同的测试得到不同的结果

标签 java performance long-integer java-7 jdk6

在尝试比较数据类型“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 作为计数器的数据类型,另一个使用 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中,两次测试得到相同的结果

谁能解释一下为什么会这样?

最佳答案

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,看看是否有区别。

关于java - jdk6和jdk7相同的测试得到不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12189428/

相关文章:

Java 堆空间(java.lang.OutOfMemoryError)

java - 子类实例到父类(super class)

C++ 独立数据的多线程性能

java - 加快 Java 版 WordNet 词形还原器的使用速度

c++ - 如何强制long为4字节

java - 在 long 和 double 之间进行类型转换时得到意想不到的结果

java - Struts 2中如何调整Display Tag的[last/prev] [next/last]链接的位置

java - 如何将自定义唯一编号分配给 GAE 中的实体?

java - 有没有办法在从 Java 中的输入流读取时将字节更改为整数?

c++ - 使用 LONG DOUBLE, "9223372036854775807 - 1"仍然丢弃最后一位数字,结果为 "9223372036854775800"