【问题标题】:Quickest way to process large number of files with thousands of Data in each file处理每个文件中包含数千个数据的大量文件的最快方法
【发布时间】:2012-03-01 18:24:08
【问题描述】:

我需要处理来自大量文件的数据,其中包含数千个行数据。之前我是逐行读取整个文件并进行处理。处理所有文件时需要花费大量时间文件增加了。然后有人说可以使用线程在更短的时间内执行任务??线程可以使这个过程更快。我使用的是c#语言。

【问题讨论】:

  • 如何处理它们?进入数据库或其他方式?
  • 你的瓶颈在哪里?如果是磁盘 IO,那么线程可能会使其变慢。 (我在这里对您的设置进行假设...)
  • 请注意,当您读取所有文件数据时,再分析这些数据比逐行读取要好..
  • 文件的每一行有2个电话号码,需要在数据库中检查,然后写回另一个文件
  • 您应该提供更多信息,例如.. 文件以逗号分隔、制表符分隔、固定长度、可变长度等...线程也很好,但我认为最重要的问题应该是什么您尝试处理的文件/文件信息类型

标签: c# multithreading performance file


【解决方案1】:

当然可以,尽管这取决于所讨论的特定工作。一种非常常见的模式是让一个线程执行文件 IO,而多个线程处理实际的行。

启动多少处理线程取决于您的系统上有多少处理器/内核,以及处理结果的写出方式。但是,如果每行的处理时间非常短,则使用多个处理线程可能不会获得太多的速度提升,而单个处理线程将是最佳选择。

【讨论】:

  • 该行的“处理”涉及与数据库的通信,因此拥有比处理器更多的线程可能是有益的,这样当一个线程阻塞数据库调用时,另一个线程可以设置一个,做文件IO等
  • 同意@Servy,尽管您可能会发现只需几个工作线程即可将您的程序从 IO 绑定变为数据库绑定。
  • 你的意思是相反的吗?我想它会从数据库绑定开始,而不是 IO 绑定。有了足够多的工作线程,您就可以将其更改为 IO 绑定,具体取决于设置方式、所有设备的硬件规格等。
  • 抱歉,我没说清楚。现在,从文件读取、网络(如果是远程数据库)和数据库写入的角度来看,您主要受 IO 限制。在某个时候,如果有足够的工作人员,您将最大限度地利用数据库的容量来处理负载。
  • 是的,您的线程最大值应该基于数据库可以有效支持的请求数。这将基于与数据库通信的延迟、查询的复杂性(以及它接触的数据以及查询是否在它们接触的数据中重叠)、数据库的硬件规格、等等。在实践中,您可以只运行具有各种线程池大小的程序并比较时间。我不会在学术上猜测最佳值,而是采用实验机制。 (无论哪种方式,它都不会与核心数量密切相关)。
【解决方案2】:

性能问题的好处是假设您的代码只是在做一些不必要的事情,并尝试找出它是什么 - 测量、审查、绘制 - 任何适合您的东西。我并不是说您的代码很慢,这只是一种查看方式。

首先将多线程添加到混合中,您可能会发现分析代码要困难得多。

更具体地为您的任务:将多个类似的操作(如从文件中读取记录或提交到数据库)组合在一起可能节省大量时间(您需要原型和测量)。

【讨论】:

    【解决方案3】:

    我建议您对数据库进行批量插入。

    您可以有一个线程将一行读取到并发队列中。而其他线程正在从并发队列中提取数据。如有必要或您正在对其进行任何操作,请对其进行聚合。然后将数据批量插入数据库。它会为您节省很多时间。

    在 db 中插入一行会很慢。你必须做批量插入。

    【讨论】:

    • 我们实际上并没有将数据逐行插入到数据库中。我们处理整个文件并将处理后的数据完全写入另一个文件,然后将文件加载到数据库中。
    • 好的。我不知道你的 impl 细节,但如果你想提高你的 IO 性能,请查看异步 IO,例如 beginXXX 方法。除此之外,对于 IO 绑定操作,您无能为力。
    【解决方案4】:

    是的,使用线程可以加快计算速度。
    当您有时间处理可以在后台运行的任务时,将使用线程(例如,当您处理 10 个文件但只需要一个文件时,您可以对每个文件进行一个线程处理,这将比处理它们快得多都在你的主线程上)。

    请注意,可能存在相关的错误,因此您应该确保所有线程都已完成运行,然后再继续并尝试访问它们所获得的内容。

    查找“C#.NET 多线程” 任何线程都可以运行指定的函数,后台工作者也是一个不错的类(不过我更喜欢纯多线程)。

    另请注意,这可能会适得其反并导致速度变慢,但尝试一下是个好主意。

    【讨论】:

    • 在这里使用多线程可能是个错误;特别是对于磁盘。这可能会导致磁盘在执行随机访问而不是顺序访问时发生锤击,并大大降低缓冲区的有效性
    • 也许可以,但尝试一下仍然是个好主意。无论如何,这可能会发生,但可能不会。这里的目标是提高效率,如果它成功了,那就顺其自然吧。如果没有,请撤消更改并找到其他方法,对吗?
    【解决方案5】:

    线程是让您将处理与 I/O 重叠的一种方式(还有其他方式)。这意味着总时间不是读取数据的时间和处理数据的时间的总和,您可以将其减少到(大致)两者中较大的一个(通常是 I/O 时间)。

    如果您主要希望重叠 I/O 时间,则可能需要查看重叠的 I/O 和/或 I/O 完成端口。

    编辑:如果您要这样做,您通常希望 I/O 线程的数量基于您要从中读取的单独物理磁盘的数量,以及处理线程的数量您可用于处理的处理器数量(但只有跟上阅读器线程提供的数据所需的数量)。对于典型的台式机,这通常意味着只有两个线程,一个用于读取,一个用于处理数据。

    【讨论】:

    • 线路的“处理”涉及与数据库的通信,因此这很可能成为瓶颈。相比之下,文件 IO 会相当小,因此实际上不需要重叠 IO。它充其量不会改变任何事情。
    • @Servy:是的,查看 cmets,以及他的“处理”处理数据库这一事实,这可能是他需要花费精力的地方。
    猜你喜欢
    • 2022-08-18
    • 1970-01-01
    • 2010-12-15
    • 2013-07-17
    • 2014-10-08
    • 2015-07-29
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多