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

标签 c# .net windows performance filesystems

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

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 技术( SATASSDSCSI 等)以及文件所在分区的片段大小(我们可以在格式化期间定义分区)。

但是问题来了: 是否有任何公式或最佳实践来定义缓冲区大小?目前,我是根据反复试验来定义的。

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

这里有一些旧帖子非常有用,但我仍然不明白原因:

最佳答案

Sequential File Programming Patterns and Performance with .NET ”是一篇关于提高 I/O 性能的好文章。

this 的第 8 页中PDF文件,它表明缓冲区大小大于八个字节的带宽是恒定的。考虑到这篇文章是 2004 年写的,硬盘驱动器是“Maxtor 250 GB 7200 RPM SATA disk”,结果应该因最新的 I/O 技术而有所不同。

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

In un-buffered I/O, the disk data moves directly between the application’s address space and the device without any intermediate copying.

总结

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

关于c# - 使用 BinaryReader 读取大文件(>1 GB)时,最佳缓冲区大小是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19558435/

相关文章:

c# - 如果字符串包含整数,如何为文本框设置条件

windows - 如何使用 Perl 从 Windows 命令行获取文件的 SHA1 哈希值?

c# - RedirectToAction 不适用于 $.post

c# - 为什么异常总是被接受为返回类型(抛出时)?

c# - 在没有 Entity Framework 的情况下使用 C# 进行数据库交互

c# - 如果隐式已在 C# 中重载,则重载显式运算符是否有好处?

.net - 在继承实体 (TPH) 中映射导航属性

java - 有没有一种快速简便的方法将 winzip (或 Windows 内置提取器)与 jar 文件关联?

c++ - 崩溃时如何为我的进程创建小型转储?

c# - 使用语句不能正常工作