我正在测试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读取相比,似乎整数加法占主导地位.
我写了另一个基准程序只是为了证明我的猜测,它与上面的例子做了相同数量的添加.
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()似乎非常快:(从评论中提取)
我能想到的两个可能的原因:
JIT> Dead Code Elimination正在优化除最后一次迭代之外的所有迭代.
> I / O缓冲:操作系统在第一次读取后将整个文件缓冲到内存中.*
*因此后续通行证将非常快.通过每次重新排序测试或清除I / O缓存,可以轻松测试此情况