高效写入文件——立即收集或写入
Writing files efficiently — Collect or write immediately
以下两种方法对文件 I/O 的性能是否存在差异?
- 使用生产者填充的队列,并在所有数据到达后启动写入磁盘的任务
- 有一个与生产者并行写入磁盘的任务
数据写入不同的文件和多个目录。
I/O 和 Parallel.ForEach 的单独任务将在这两种情况下使用。
我假设第二个版本会表现得更好,理论上生产者和 I/O 是真正并发的。由于 I/O 会导致调用过程中断,我想知道是否会有缺点。这可能会导致开销超过并行的好处。
在某些情况下我应该更倾向于第一个解决方案而不是第二个?
I would assume that the second version would perform better
如果多个目录仍在同一个物理驱动器上,您可能会使用第二个选项获得更差的性能。
在某些边缘情况下,并行编写(并将自己限制在 2 或 3 个线程)可能会更快。例如,由于创建文件的开销成本超过了写入文件的 IO 成本,因此写入 1000 个 1kb 的文件在稍微并行的情况下会表现得更好。但是,如果您要写入 1000 个 1mb 文件,那么使用单个线程进行写入可能会更快。
一个简单的实现方法是使用 TPL Dataflow,你可以有一个高度并行的 TransformBlock
,然后将其连接到执行写入的 1 或 2 线程 ActionBlock
.然后,在设置 link 时限制 ActionBlock
的输入缓冲区,如果管道已满,TransformBlock
将阻止生产者,而不会占用大量内存。
我不确定你所说的第二个任务是什么意思。我认为您是在谈论使用某种并发队列和为其提供服务的消费者线程。生产者写入该队列。消费者线程等待信息被添加到队列中,并将该信息写入磁盘。这样,消费者可以在生产者处理并将事物添加到队列的同时写入磁盘。无需等待所有信息到达。
我在使用 BlockingCollection 这样的事情上取得了很多成功。
如果这就是您所说的,那么它应该比您的第一个选项执行得更好,因为正如您所说,磁盘 I/O 线程和生产者线程正在同时执行。
以下两种方法对文件 I/O 的性能是否存在差异?
- 使用生产者填充的队列,并在所有数据到达后启动写入磁盘的任务
- 有一个与生产者并行写入磁盘的任务
数据写入不同的文件和多个目录。 I/O 和 Parallel.ForEach 的单独任务将在这两种情况下使用。
我假设第二个版本会表现得更好,理论上生产者和 I/O 是真正并发的。由于 I/O 会导致调用过程中断,我想知道是否会有缺点。这可能会导致开销超过并行的好处。
在某些情况下我应该更倾向于第一个解决方案而不是第二个?
I would assume that the second version would perform better
如果多个目录仍在同一个物理驱动器上,您可能会使用第二个选项获得更差的性能。
在某些边缘情况下,并行编写(并将自己限制在 2 或 3 个线程)可能会更快。例如,由于创建文件的开销成本超过了写入文件的 IO 成本,因此写入 1000 个 1kb 的文件在稍微并行的情况下会表现得更好。但是,如果您要写入 1000 个 1mb 文件,那么使用单个线程进行写入可能会更快。
一个简单的实现方法是使用 TPL Dataflow,你可以有一个高度并行的 TransformBlock
,然后将其连接到执行写入的 1 或 2 线程 ActionBlock
.然后,在设置 link 时限制 ActionBlock
的输入缓冲区,如果管道已满,TransformBlock
将阻止生产者,而不会占用大量内存。
我不确定你所说的第二个任务是什么意思。我认为您是在谈论使用某种并发队列和为其提供服务的消费者线程。生产者写入该队列。消费者线程等待信息被添加到队列中,并将该信息写入磁盘。这样,消费者可以在生产者处理并将事物添加到队列的同时写入磁盘。无需等待所有信息到达。
我在使用 BlockingCollection 这样的事情上取得了很多成功。
如果这就是您所说的,那么它应该比您的第一个选项执行得更好,因为正如您所说,磁盘 I/O 线程和生产者线程正在同时执行。