有效地编写文件 - 立即收集或写入

时间:2016-03-02 19:57:10

标签: c# file io task parallel.foreach

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

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

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

我认为第二个版本的性能会更好,理论上生产者和I / O实际上是并发的。由于I / O导致调用进程中断,我想知道是否存在漏洞。这可能会导致开销超过并行性的好处。

有没有情况我应该赞成第一个解决方案?

2 个答案:

答案 0 :(得分:0)

  

我认为第二个版本会表现得更好

如果多个目录仍然在同一个物理驱动器上,那么使用第二个选项可能会降低性能。

有些边缘情况并行写入(并且仅限于2或3个线程)可以更快。例如,由于创建文件的开销成本超过了写入文件的IO成本,因此编写1000个1kb文件会在略微并行的情况下表现更好。但是,如果您在写1000个1mb文件的地方,那么单个线程进行写入可能会更快。

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

答案 1 :(得分:0)

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

我使用BlockingCollection做了很多成功。

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