使用BinaryReader读取大文件(> 1 GB)时,最佳缓冲区大小是多少?

Ami*_*ian 10 .net c# windows filesystems performance

我正在阅读二进制文件,这是一个示例:

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16*1024];
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        ......
    }

}
Run Code Online (Sandbox Code Playgroud)

显然缓冲区大小(16*1024)在性能方面有很大的作用.我读过它取决于I/O技术(SATA,SSD,SCSI)等)以及它上面存在文件的分区的片段大小(我们可以在格式化分区期间定义).

但问题: 是否有任何公式或最佳实践来定义缓冲区大小?现在,我正在根据反复试验来定义.

编辑: 我已经在我的服务器上测试了不同缓冲区大小的应用程序,并且我获得了4095*256*16(16 MB)的最佳性能!4096慢了4秒.

以下是一些非常有用的旧帖子,但我仍然无法得到原因:

小智 7

" 顺序文件编程模式和.NET性能 "是I/O性能改进的一篇伟大文章.

PDF文件的第8页中,它显示缓冲区大小大于8个字节的带宽是不变的.考虑到该文章是在2004年编写的,硬盘驱动器是" Maxtor 250 GB 7200 RPM SATA磁盘 ",结果应该是最新的I/O技术不同.

如果您正在寻找最佳性能,请查看pinvoke.net或PDF文件的第9页,未缓冲的文件性能测量结果显示更好的结果:

在未缓冲的I/O中,磁盘数据直接在应用程序的地址空间和设备之间移动,无需任何中间复制.

摘要

  • 对于单个磁盘,使用.NET框架的默认值 - 它们为顺序文件访问提供了出色的性能.
  • 在创建文件时预分配大型顺序文件(使用SetLength()方法).与碎片文件相比,这通常可将速度提高约13%.
  • 至少就目前而言,磁盘阵列需要非缓冲I/O才能实现最高性能 - 缓冲I/O比未缓冲I/O慢8倍.我们预计这个问题将在.NET框架的后续版本中得到解决.
  • 如果您自己进行缓冲,请使用大型请求(64 KB是一个很好的起点).使用.NET框架,单个处理器可以使用未缓冲的I/O以超过800 Mbytes/s的速度读写磁盘阵列.


归档时间:

查看次数:

9114 次

最近记录:

10 年,2 月 前