今天早些时候感到无聊,我开始考虑Java中缓冲和无缓冲字节流的相对性能。作为一个简单的测试,我下载了a reasonably large text file并编写了一个简短的程序来确定缓冲流在复制文件时的效果。进行了四项测试:
毫不奇怪,使用缓冲的输入和输出流比使用无缓冲的流快几个数量级。然而,真正有趣的事情(至少对我而言)是案例2和3之间的速度差异。一些样本结果如下:
Unbuffered input, unbuffered output
Time: 36.602513585
Buffered input, unbuffered output
Time: 26.449306847
Unbuffered input, buffered output
Time: 6.673194184
Buffered input, buffered output
Time: 0.069888689
对于有兴趣的人,代码可用here at Github。任何人都可以解释为什么案例2和案例3的时间如此不对称?
答案 0 :(得分:10)
当您读取文件时,其下面的文件系统和设备会执行各种级别的缓存。他们几乎从不读过一个字节;他们看了一块。在随后读取下一个字节时,该块将位于缓存中,因此速度会快得多。
有理由认为,如果你的缓冲区大小与块大小相同,那么缓冲输入流实际上并没有获得那么多(它节省了一些系统调用,但就实际物理而言) / O它不会为你节省太多的钱。)
当您编写文件时,文件系统无法为您缓存,因为您没有给它写积压的东西。它可能会为您缓冲输出,但它必须对刷新缓冲区的频率做出有根据的猜测。通过自己缓冲输出,您可以让设备一次完成更多工作,因为您手动构建了积压工作。
答案 1 :(得分:2)
对于标题问题,缓冲输出更有效。原因是硬盘驱动器(HDD)将数据写入其扇区的方式。特别是考虑碎片磁盘。读取速度要快得多,因为磁盘已经知道数据的位置,而不是必须确定它适合的位置。使用缓冲区,磁盘将找到比无缓冲方式更大的连续空白空间来保存数据。 为咯咯笑声运行另一个测试。在磁盘上创建一个新分区并运行测试读取和写入清理平板。要比较苹果和苹果,请在测试之间格式化新创建的分区。如果您运行测试,请在此之后发布您的号码。
答案 2 :(得分:1)
一般来说,写入对计算机来说比较繁琐,因为它在读取时无法缓存。一般来说,它与现实生活非常相似 - 阅读比写作更快更容易!