【问题标题】:FileStream slow, Fast way read read few bytes of many filesFileStream 慢,快速读取许多文件的几个字节
【发布时间】:2019-11-08 10:27:15
【问题描述】:

我需要读取和处理超过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 协议访问的网络驱动器,但文件保存在多个物理磁盘上。

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

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

【问题讨论】:

标签: c# .net-core io batch-processing filestream


【解决方案1】:

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 下使用它,它就可以工作。

【讨论】:

    【解决方案2】:

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

    您运行处理文件的循环的另一个任务是非常标准的。如果没有别的,只是为了不锁定主/GUI线程。

    但所有形式的多任务处理并不是神奇的“让事情变得更快”的子弹。如果您将其应用于错误的问题,您最终会得到更复杂/更容易出错、需要更多内存且最重要的是更慢的代码,然后是简单的顺序代码。

    现在文件处理通常是磁盘或网络绑定操作。你只得到 4 个字节,所以我猜你并没有为每个文件做很多自定义 CPU 工作。所以这里唯一的 CPU 工作将是手柄的打开和关闭。除非您对磁盘/网络使用一些antique like PIO,否则我很确定它几乎没有。磁盘/网络绑定也是如此。

    有一些通过互联网连接和每个连接限制的边缘案例,但我怀疑它们是否适用于此。而且通常每个文件的多任务处理并没有加快任何速度。

    【讨论】:

    • 我不确定,因为实际上使用多线程它大约快 20%,我在 2 个线程时获得了最好的改进,超过 4 个线程增加是微不足道的,超过 8 个线程没用,因为前一个线程在我开始新线程之前就终止了。
    • 但是是的,我明白,这与磁盘 I/O 无关,简单我得到更好的性能,因为当我等待 I/O 操作的结果时,我可以做我的其他阐述并编写数据库中的结果。
    • @StefanoBalzarotti 我猜这 20% 是因为您在网络的使用方面存在一些差距。硬盘很慢。但是网络仍然比它慢。 |唯一真正的加速是切断网络。您需要将磁盘获取到代码,或者将代码获取到磁盘。
    • 无论如何你在说什么我认为它仅适用于所有操作都在单个物理磁盘上进行的情况,卷是一个,但操作是在具有 RAID 的多个磁盘上进行的。我不太确定架构,因为我从 newtork 驱动器访问,但肯定有几个物理磁盘。为什么我不能同时访问两个不同磁盘中的两个文件?
    • 而且我不认为网络慢,因为如果问题是网络,磁盘上的所有操作都会很慢,例如File.Exist,但file.Exist执行时间无关紧要.唯一非常慢的操作是 FileStream.Open
    猜你喜欢
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多