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

标签 c# optimization file size buffer

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

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

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

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

最佳答案

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

4 KB 是一个传统的选择,尽管这只会在偶然情况下正好跨越一个虚拟内存页面。很难分析;您最终将测量读取缓存文件所需的时间。它以 RAM 速度运行,如果数据在缓存中可用,速度为 5 GB/秒或更高。第二次运行测试时它将在缓存中,并且在生产环境中不会经常发生这种情况。文件 I/O 完全由磁盘驱动器或 NIC 控制并且速度非常慢,复制数据是花生。 4 KB 就可以了。

关于c# - 带流的文件 I/O - 最佳内存缓冲区大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3033771/

相关文章:

python - 在Python中连接来自connection.recv()的数据包

java - 尝试使用 java 8 递归列出系统根目录中的所有文件时出现 "Config.Msi"目录问题

c# - 为什么不尽可能使用 "in"作为方法参数呢?

c# - 在c#中移动后无法删除文件

c - 如何在线程安全 C 库中高效实现句柄

java - 更新Map值的有效方法

c# - Visual Studio 2013 不重新创建 pdb 文件

c# - Nancy Razor 部分 View 不在 Release模式下呈现

c++ - 减少编译时间的奇怪 C++ 模式

python - Windows错误 : [Error 32] The process cannot access the file because it is being used by another process: 'new.dat'