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

AJ.*_*AJ. 50 c# size optimization buffer file

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

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

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

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

Han*_*ant 71

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

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

  • 文档是正确的,.NET Reflector显示`_DefaultCopyBufferSize`的值为"0x14000"(81920或80K).但是,这适用于从流到流的复制,而不是缓冲数据.[BufferedStream类](http://msdn.microsoft.com/en-us/library/system.io.bufferedstream(v = vs.110).aspx)的`_DefaultBufferSize`为"0x1000"(4096或4k) ),这将是一个更好的类,以了解.NET框架用于流的缓冲区大小. (8认同)
  • 4KB是.net框架使用的默认值:http://msdn.microsoft.com/en-us/library/dd783870.aspx (3认同)