C#从许多文件中快速读取CSV

时间:2011-01-07 06:07:48

标签: c# csv bulk

我有一个包含3000个csv文件的文件夹,大小从1Kb到100kb不等。这些文件中的每一行都是43个字符。它们的总大小为171Mb。

我正在尝试编写一个程序来尽可能快地解析这些文件。

我最初尝试过自己的实现,但对这些结果并不满意。然后我在StackOverflow上找到了LumenWorks.Framework.IO.Csv。它有大胆的主张:

  

为了提供更实际的数字,使用包含145个字段和50,000条记录的45 MB CSV文件,阅读器处理大约30 MB /秒。总而言之,耗时1.5秒!机器规格为P4 3.0 GHz,1024 MB。

我根本没有得到任何接近这些结果的东西。我的过程需要>> 10分钟。这是因为它不是一个大流,但很多小文件,那里有开销?还有什么我可以做的吗?

我觉得LumenWorks实现并不比我自己快(我没有基准测试),更不用说它处理引号,转义,注释和多行字段,我都不需要。我有一个非常规则的逗号分隔整数格式。

干杯

4 个答案:

答案 0 :(得分:4)

CSV文件解析受I / O限制,取决于您从磁盘读取数据的速度。对于消费级硬盘而言,最快的速度是每秒50到60 MB。听起来像这个LumenWorks接近这个限制。

虽然在一个带有一个大文件的干净的未碎片化磁盘上,您只能获得这种吞吐量。因此,磁盘读取器头只需要抽取数据而不必移动很多,只需跟踪到磁道移动即可。移动头部是缓慢的部分,通常平均约为16毫秒。

当您阅读3000个文件时,有批次的头部运动。打开文件大约需要50毫秒。至少做一个类似的测试来找到瓶颈。使用好的文本编辑器并复制/粘贴也可以创建一个巨大的文件。首先运行磁盘碎片整理程序,Defraggler是一个不错的免费版本。

就代码改进而言,请注意字符串。它们可以生成大量垃圾并且具有较差的CPU缓存局部性。线程无法使I / O绑定代码更快。唯一可能的改进是一个读取文件的线程,另一个执行转换以便读取和转换重叠。有多个线程进行读取是没有意义的,他们只是轮流等待磁盘。

注意文件系统缓存。第二次在同一个文件上运行测试时,您将从内存中获取数据,而不是磁盘。这很快但不会告诉你它将如何在生产中发挥作用。

答案 1 :(得分:0)

是否会立即“显示”所有文件以进行处理?您是否可以逐步合并它们,因为它们“到达”一个由您的程序处理的文件? 10分钟处理+/- 7MB数据需要很长时间(最差情况来自您引用的数字)?

答案 2 :(得分:0)

尝试在单独的线程上读取文件。 如果需要同步读取数据,您可以尝试创建线程来处理文件句柄的打开/关闭并实现队列以在单个线程中实际解析数据

答案 3 :(得分:0)

您是否尝试过使用LogParser? 我不确定它会更快,但我在某些情况下取得了成功。 值得快速测试。

log parser 2.2

可能更快的是从你的例子中读取许多小的CSV。无论如何,无论你是否应该对自己的代码进行基准测试,以便将它与流明和logparser(以及任何其他建议)进行比较。假设很糟糕。