Java中的整数加法性能

时间:2012-01-31 17:05:19

标签: java performance integer addition

我正在测试Java中整数加法的性能。我这样做的方法是总结数十亿的整数。我用于测试的示例文件是1G二进制文件。我的程序非常简单,如下面的代码段所示。

int result = 0;
FileChannel fileChannel = new FileInputStream(filename).getChannel();
long fileSize = fileChannel.size();
intBuffer = fileChannel.map(MapMode.READ_ONLY, startPosition, fileSize).asIntBuffer();

try {
  while (true) {
    result += intBuffer.get();
  }
} catch (BufferUnderflowException e) {
  System.out.println("Complete reading");
}

从上面可以看出,它只是在每个循环中执行两个操作

  • 从文件中读取整数
  • 整数加法

这个程序在我的机器上跑了大约2分钟。通过将result += intBuffer.get()更改为result = intBuffer.get()(如下面的代码段所示),我还在没有添加的情况下进行了另一次测试运行。

int result = 0;
FileChannel fileChannel = new FileInputStream(filename).getChannel();
long fileSize = fileChannel.size();
intBuffer = fileChannel.map(MapMode.READ_ONLY, startPosition, fileSize).asIntBuffer();

try {
  while (true) {
    result = intBuffer.get();
  }
} catch (BufferUnderflowException e) {
  System.out.println("Complete reading");
}

在这种情况下,整个程序在1秒内完成。与上面的兄弟变体相比,与IO读取相比,似乎整数加法占据了CPU时间。

我写了另一个基准程序只是为了证明我的猜测,它与上面的例子有相同数量的添加。

int result = random.nextInt();
int other = random.nextInt();
int num = 1073741824 / 4;
while(num-- > 0) {
  result += other;
}

使用相同数量的整数加法加上整数增量运算,此程序的完成时间不到1秒。

我的问题是

  • 导致这些运行之间的主要时间差异的原因是什么? Java编译器是否会对最后一个进行优化?

任何想法都表示赞赏。

3 个答案:

答案 0 :(得分:4)

这是因为与CPU相比,磁盘I / O非常慢。

在第一种情况下,您正在读取文件。所以你受到磁盘访问的约束。

在第二种情况下,它全部在CPU中。


所以这与加法的速度无关。

  • 第一种情况受到磁盘速度的限制。
  • 第二种情况(可能)受随机数发生器的速度限制。

至于为什么result = intBuffer.get()似乎非常快:(摘自评论)

我能想到的两个可能的原因:

    JIT的
  • Dead Code Elimination 正在优化除最后一次迭代以外的所有内容。
  • I / O缓冲:操作系统在第一次读取后将整个文件缓冲到内存中。*

*所以随后的传球将非常快。通过重新排序测试或每次清除I / O缓存,可以很容易地测试这种情况

答案 1 :(得分:1)

最大的区别在于您正在执行文件IO。求和整数不是问题。但它正在阅读它们。我不是很确定,但我认为在两分钟内读取1 GB的数据是可以接受的。

答案 2 :(得分:0)

这是因为I / O访问是您的瓶颈。仅在添加阶段计算时间。您始终可以将所有数据加载到RAM(例如int数组)并从此开始计算时间。

无论您做什么基准测试,请记住,数据准备阶段不应计入算法的执行时间。