我正在测试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秒。
我的问题是
任何想法都表示赞赏。
答案 0 :(得分:4)
这是因为与CPU相比,磁盘I / O非常慢。
在第一种情况下,您正在读取文件。所以你受到磁盘访问的约束。
在第二种情况下,它全部在CPU中。
所以这与加法的速度无关。
至于为什么result = intBuffer.get()
似乎非常快:(摘自评论)
我能想到的两个可能的原因:
*所以随后的传球将非常快。通过重新排序测试或每次清除I / O缓存,可以很容易地测试这种情况
答案 1 :(得分:1)
最大的区别在于您正在执行文件IO。求和整数不是问题。但它正在阅读它们。我不是很确定,但我认为在两分钟内读取1 GB的数据是可以接受的。
答案 2 :(得分:0)
这是因为I / O访问是您的瓶颈。仅在添加阶段计算时间。您始终可以将所有数据加载到RAM(例如int数组)并从此开始计算时间。
无论您做什么基准测试,请记住,数据准备阶段不应计入算法的执行时间。