高效写入文件 — 立即收集或写入

本文关键字:文件 高效 | 更新日期: 2023-09-27 18:37:08

以下两种方法之间的文件 I/O 性能是否存在差异?

  • 使用由生产者填充的队列,并在所有数据到达后开始写入磁盘的任务
  • 将任务写入磁盘并行到生产者

数据将写入不同的文件和多个目录。在这两种情况下,将使用 I/O 和 Parallel.ForEach 的单独任务。

我假设第二个版本会表现得更好,理论上生产者和 I/O 实际上是并发的。由于I/O导致调用过程中断,我想知道是否会有缺点。这可能会导致开销超过并行性的好处。

在有些情况下,我应该倾向于第一种解决方案而不是第二种解决方案?

高效写入文件 — 立即收集或写入

我假设第二个版本会表现得更好

如果多个目录仍位于同一物理驱动器上,则使用第二个选项可能会获得更差的性能。

在某些边缘情况下,并行编写(并将自己限制为仅 2 或 3 个线程)可能会更快。例如,由于创建文件的开销成本超过了写入文件的 IO 成本,因此写入 1000 个 1kb 文件在稍微并行的 fasion 中性能更好。但是,如果您在哪里写入 1000 个 1mb 文件,那么让单个线程进行写入可能会更快。

实现这一点的一种简单方法是使用 TPL 数据流,您可以有一个高度并行的TransformBlock但随后将其连接到执行写入的 1 或 2 线程ActionBlock。然后,在设置链接时限制ActionBlock的输入缓冲区,如果管道已满而不占用大量内存,则TransformBlock将阻止生产者。

我不确定你说的第二个任务是什么意思。我想你说的是使用某种并发队列,以及为它提供服务的使用者线程。生产者写入该队列。使用者线程等待信息添加到队列中,并将该信息写入磁盘。这样,使用者可以在生产者处理内容并将其添加到队列时写入磁盘。无需等待所有信息到达。

我在使用BlockingCollection做这样的事情上取得了很大的成功。

如果这就是你所说的,那么它的性能应该比你的第一个选项好得多,因为正如你所说,磁盘 I/O 线程和生产者线程同时执行。