java - Java中的整数加法性能

标签 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 编译器是否会优化最后一个?

如有任何想法,我们将不胜感激。

最佳答案

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

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

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


所以这与添加速度无关。

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

至于为什么result = intBuffer.get()看起来很快:(摘自评论)

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

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

*所以后面的pass会很快。通过重新排序测试或每次清除 I/O 缓存,很容易测试这种情况

关于java - Java中的整数加法性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9083736/

相关文章:

c++ - 在 C++ 中存储、加载和使用倒排索引的最佳方式 (~500 Mo)

performance - F# 似乎比其他语言慢...我能做些什么来加快速度?

Python评估与False相同值的整数和字符的比较

java - 在Java中手动将字符串转换为整数

php - 表中的行数到整数

java - 使用 SharedPreferences 仅 setText() 有效,但append() 无效

java - 在java中解析二次方程

python - 为什么这个循环比创建字典的字典理解更快?

Java(ME) SQLite 数据类型不匹配的恶性循环

c# - java 服务器 <-> c# + javascript + java + * 客户端