FileStream 慢速,快速读取方式读取许多文件的几个字节

FileStream slow, Fast way read read few bytes of many files

我需要读取和处理超过1亿个文件,但我只需要读取每个文件的前4个字节,因为我只需要读取文件头。
我已经创建了一个 .net core 2.2 批处理来处理它们,并且我已经使用多线程来最大化并发处理,但是在我想到的所有可能的优化之后它仍然需要太多时间。
我做了分析基准测试,78% 的时间用于打开文件流:File.OpenRead(filePath).
相比之下,File.Exist(filePath) 和 Director.Exist(dirPath) 要快得多。
即使是我预计会很慢的 Directory.GetFiles(dirPath) 函数,它也只需要全局执行时间的 4%。

另外 15% 的时间用于有效地从流中读取数据。

我从文档中了解到默认缓冲区大小为 4096 字节,因此首先尝试减少到​​ 4 字节,但性能没有显着变化,但我认为保留 4096 是正确的,因为它是簇大小文件系统。

该卷是使用CIFS协议访问的网络驱动器,但文件保存在多个物理磁盘上。

为什么只打开流这么慢?可能是因为它需要检查用户权限?

您能否建议一种更快的访问所有文件的方法?

我想是时候发表我的多任务免责声明了:

另一个任务是 运行 遍历文件的循环非常标准。如果不出意外,只是为了不锁定 main/GUI 线程。

但是,所有形式的多任务处理都不是神奇的 "make things faster" 子弹。如果你将它应用到错误的问题上,你最终得到的代码更 complex/more 容易出错,需要更多的内存,最重要的是 比简单的顺序代码更慢

现在文件处理通常是磁盘或网络绑定操作。你只有 4 个字节,所以我猜你没有为每个文件做很多自定义 CPU 工作。所以这里唯一的 CPU 工作就是打开和关闭手柄。我敢肯定,除非你为 disks/Network 使用一些 antique like PIO,否则几乎什么都没有。所以也 Disk/Network 绑定。

有一些边缘案例涉及 Internet 连接和每个连接限制,但我怀疑它们是否适用于此。通常每个文件的多任务处理不会加快任何速度。

FileStream 比其他 API、File.Exist、Directory.GetFiles 等慢,因为它执行大量 SMB 调用以规范化路径、需要权限等

你可以在那里得到更好的答案Why is .NET's File.Open with a UNC path making excessive SMB calls?

所以加速流的最佳方法是直接调用本机 API 避免大多数控件。

我发现这个很好用的库:https://github.com/i-e-b/tinyQuickIO

该库的唯一问题是它不以 .NET Core 或 .NET 标准为目标,但如果您在 windows 下使用它,它就可以工作。