带有流的文件 I/O - 最佳内存缓冲区大小

Posted

技术标签:

【中文标题】带有流的文件 I/O - 最佳内存缓冲区大小【英文标题】:File I/O with streams - best memory buffer size 【发布时间】:2011-03-03 07:17:20 【问题描述】:

我正在编写一个小型 I/O 库来协助一个更大的(爱好)项目。该库的一部分对文件执行各种功能,通过FileStream 对象读取/写入。在每个StreamReader.Read(...) 传递中,

我触发了一个事件,该事件将在主应用程序中用于显示进度信息。循环中进行的处理是多种多样的,但不会太耗时(例如,它可能只是一个简单的文件副本,或者可能涉及加密......)。

我的主要问题是:使用的最佳内存缓冲区大小是多少?考虑物理磁盘布局,我可以选择 2k,这将覆盖一个 CD 扇区大小,并且是 512 字节硬盘扇区的一个很好的倍数。在抽象树的更高层,您可以选择更大的缓冲区,一次可以读取整个 FAT 簇。我意识到,对于今天的 PC,我可以选择更消耗内存的选项(例如,几个 MiB),但随后我会增加 UI 更新之间的时间,并且用户会感觉到应用程序的响应速度较慢。

顺便说一句,我最终希望为托管在 FTP/HTTP 服务器上的文件(通过本地网络/fastish DSL)提供类似的接口。对于那些来说,最好的内存缓冲区大小是多少(同样,感知响应能力与性能之间的“最佳情况”权衡)?

【问题讨论】:

可能会有帮助:***.com/questions/19558435/… 我原以为操作系统或 Windows 会维护自己的硬件功能和速度配置文件,并提供一项服务,为给定的存储量和活动推荐最佳缓冲区大小(例如随机读取/writes vs 顺序读/写) - 这将消除猜测。 C# FileStream : Optimal buffer size for writing large files?的可能重复 【参考方案1】:

当我直接通过流对象处理文件时,我通常使用 4096 字节。它似乎在多个 I/O 区域(本地文件系统、LAN/SMB、网络流等)上相当有效,但我还没有分析它或任何东西。很久以前,我看到几个例子使用了这个尺寸,它留在了我的记忆中。但这并不意味着它是最好的。

【讨论】:

对。我永远不会使用小于 4k 的任何东西,因为它是由虚拟内存系统(磁盘缓存所基于)管理的最小块。【参考方案2】:

“视情况而定”。

您必须使用不同的缓冲区大小测试您的应用程序以确定最佳选择。你无法提前猜测。

【讨论】:

【参考方案3】:

文件已被文件系统缓存缓冲。您只需要选择一个缓冲区大小,该大小不会强制 FileStream 使本机 Windows ReadFile() API 调用过于频繁地填充缓冲区。不要低于 1 KB,超过 16 KB 会浪费内存,并且对 CPU 的 L1 cache(通常为 16 或 32 KB 的数据)不友好。

4 KB 是一个传统的选择,即使它恰好跨越一个虚拟内存页面只是偶然。很难描述;您最终将测量读取缓存文件需要多长时间。如果数据在缓存中可用,它以 RAM 速度运行,5 GB/秒或更高。它将在您第二次运行测试时在缓存中,而这在生产环境中不会经常发生。文件 I/O 完全由磁盘驱动器或NIC 主导,而且速度非常慢,复制数据是小菜一碟。 4 KB 就可以了。

【讨论】:

较小的缓冲区大小(如 4-8kb)也是可取的,因为 CPU 缓存可以容纳这样的数量。但是,如果您选择较小,则可能会从内核转换中积累大量开销。 @HansPassant:我的应用程序同时处理大量小文件以及单独处理大文件。 4KB 大小是否会对小于 4KB 的文件的性能产生不利影响? 4KB 是 .net 框架使用的默认值:msdn.microsoft.com/en-us/library/dd783870.aspx 如果文档正确,在 4.5 中他们将默认值增加到 81920。 文档是正确的,.NET Reflector 显示 _DefaultCopyBufferSize 的值为 0x14000(81920 或 80K)。但是,这是用于从流复制到流,而不是缓冲数据。 BufferedStream Class 有一个 _DefaultBufferSize0x1000(4096 或 4k),这将是一个更好的类来了解 .NET 框架用于流的缓冲区大小。【参考方案4】:

我认为默认值通常是最好的 - 因此我在internal const int 变量DefaultBufferSize 中使用4096B FileStream 类。

【讨论】:

默认并不总是最好的。对于更常见的情况,这只是一个很好的折衷方案,而不是所有负载的最佳选择。

以上是关于带有流的文件 I/O - 最佳内存缓冲区大小的主要内容,如果未能解决你的问题,请参考以下文章

在C和/或C ++中创建和管理内存中的字节缓冲区,可以根据需要自动调整大小

Java笔记:非阻塞I/O

读-处理-写的最佳缓冲区大小

java I/O流详解

流与缓冲

不用怀疑!这就是把Java.I/O流讲解的最清楚的一篇文章