3

我有一个包含 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

4 回答 4

4

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

尽管在带有一个大文件的干净整洁的磁盘上,您只会获得这种吞吐量。因此,磁盘读取器磁头只是泵送数据而不必移动很多,只是磁道到磁道的移动。移动头部是缓慢的部分,通常平均在 16 毫秒左右。

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

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

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

于 2011-01-07T06:23:32.450 回答
0

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

日志解析器 2.2

它可能更快的地方是从您的示例中的许多小型 CSV 中读取。无论如何,无论您应该对自己的代码进行基准测试,以便您可以将其与 lumens 和 logparser(以及任何其他建议)进行比较。假设是坏的。

于 2011-01-10T22:41:03.083 回答
0

所有文件是否立即“出现”以进行处理?当它们“到达”到一个由您的程序处理的文件中时,您不能将它们增量合并吗?10 分钟是处理 +/-7MB 数据的很长时间(从您引用的数字来看,最坏的情况)?

于 2011-01-07T06:18:11.630 回答
0

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

于 2011-01-07T06:18:30.547 回答