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

时间:2010-06-13 20:26:42

标签: c# optimization file size buffer

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

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

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

顺便说一句,我最终希望为FTP / HTTP服务器上托管的文件提供类似的界面(通过本地网络/快速DSL)。那些最佳的内存缓冲区大小(再次,感知响应性与性能之间的“最佳情况”权衡)?

4 个答案:

答案 0 :(得分:69)

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

4 KB是一种传统的选择,即使它只是偶然地跨越虚拟内存页面。很难描述;你最终会测量读取缓存文件所需的时间。如果数据在缓存中可用,则以RAM速度(5千兆字节/秒)运行。它将在您第二次运行测试时位于缓存中,而这在生产环境中不会经常发生。文件I / O完全由磁盘驱动器或NIC支配,并且速度极慢,复制数据是花生。 4 KB可以正常工作。

答案 1 :(得分:4)

当我直接通过流对象处理文件时,我通常使用4096字节。它似乎在多个I / O区域(本地文件系统,LAN / SMB,网络流等)中相当有效,但我没有对它进行分析。回来的时候,我看到几个例子使用那个大小,它卡在我的记忆中。这并不意味着它是最好的。

答案 2 :(得分:3)

“这取决于”。

您必须使用不同的缓冲区大小测试您的应用程序,以确定最佳效果。你不能提前猜测。

答案 3 :(得分:-1)

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