最佳缓冲区大小与许多因素有关:文件系统块大小、CPU缓存大小和缓存延迟。
大多数文件系统配置为使用4096或8192的块大小。理论上,如果您配置了缓冲区大小,以便比磁盘块多读几个字节,那么对文件系统的操作可能效率极低(也就是说,如果您将缓冲区配置为一次读取4100字节,则每次读取都需要由文件系统读取2个块)。如果块已经在缓存中,那么您将付出RAM->L3/L2缓存延迟的代价。如果您运气不好,而且块还没有在缓存中,那么您也要支付磁盘->RAM延迟的代价。
这就是为什么大多数缓冲区大小为2的原因,并且通常大于(或等于)磁盘块大小。这意味着您的流读取可能导致多个磁盘块读取-但这些读取将始终使用一个完整的块-没有浪费读取。
现在,在一个典型的流场景中,这被抵消了很大一部分,因为当您进入下一次读取时,从磁盘读取的块仍将在内存中(毕竟,我们在这里进行顺序读取)-所以您在下一次读取时最终支付的是RAM->L3/L2缓存延迟价格,而不是磁盘->RAM延迟。就大小而言,磁盘->RAM延迟太慢,几乎淹没了您可能处理的任何其他延迟。
因此,我怀疑如果您运行了一个具有不同缓存大小的测试(还没有亲自这么做),您可能会发现缓存大小会对文件系统块的大小产生很大的影响。除此之外,我怀疑事情会很快稳定下来。
有一个吨这里的情况和例外-系统的复杂性实际上是相当惊人的(仅仅得到一个处理L3->L2缓存传输是令人难以置信的复杂,它改变了每一种CPU类型)。
这就引出了“现实世界”的答案:如果你的应用程序是99%,设置缓存大小为8192并继续前进(更好的是,选择封装而不是性能,并使用BufferedInputStream隐藏细节)。如果您所处的应用程序中的1%高度依赖磁盘吞吐量,那么就可以完成您的实现,这样您就可以交换不同的磁盘交互策略,并提供旋钮和拨号,让用户能够测试和优化(或者想出一些自我优化的系统)。