我正在阅读二进制文件,这里是一个示例:
public static byte[] ReadFully(Stream input) { byte[] buffer = new byte[16*1024]; int read; while ((read = input.Read(buffer, 0, buffer.Length)) > 0) { ...... } }
缓冲区大小(16 * 1024)显然对性能有很大的作用。 我已经读过,它取决于I / O技术( SATA , SSD , SCSI等)以及其上存在的分区的分段大小(我们可以在格式化分区时定义)。
但是这里有一个问题: 是否有任何公式或最佳实践来定义缓冲区大小? 现在,我正在基于反复试验来定义。
编辑:我testing了我的服务器上的应用程序与不同的缓冲区大小,我得到了4095 * 256 * 16(16 MB)的最佳性能! 4096慢了4秒。
这里有一些旧post是非常有帮助的,但我仍然不能得到原因:
.NET中更快(不安全)的BinaryReader
最佳文件缓冲区读取大小?
文件I / O与stream – 最佳的内存缓冲区大小
在使用FileInputStream时,如何确定理想的缓冲区大小?
“ 顺序文件编程模式和与.NET性能 ”是I / O性能改进的一个伟大的文章。
在该 PDF文件的第8页,显示了大于八字节的缓冲区大小的带宽是恒定的。 考虑到这篇文章是在2004年撰写的,硬盘是“ 迈拓250 GB 7200 RPM SATA磁盘 ”,结果应该与最新的I / O技术有所不同。
如果您正在寻找最佳性能,请查看pinvoke.net或PDF文件的第9页,未缓冲的文件性能测量结果会显示更好的结果:
在未缓冲的I / O中,磁盘数据直接在应用程序的地址空间和设备之间移动,无需任何中间复制。
没有最好或最差的缓冲区大小,但你必须看一些方面。
由于您使用的是C#,所以您在Windows上运行,Windows使用NTFS ,其页面大小为4 MB,因此建议使用4096的倍数。因此,您的缓冲区大小为16*1024 = 4*4096
,这是一个不错的选择,但是要说比16*4096
更好还是更差,我们不能说。
一切都取决于情况和方案的要求。 记住在这里你不能选择最好的选择,但只有一些更好。 我建议使用4096
,但也可以使用自己的4*4096
甚至16*4096
,但请记住,这个缓冲区将被分配在堆上,所以它的分配需要一些时间,所以你不想分配一个很大的缓冲区,例如128*4096
。