我有大量(> 100k)相对较小的文件(1kb - 300kb),我需要读入和处理。我正在循环遍历所有文件并使用File.ReadAllText
来读取内容,处理它,然后读取下一个文件。这很慢,我想知道是否有一种很好的方法来优化它。
我已经尝试过使用多个线程,但由于这似乎是IO绑定,我没有看到任何改进。
答案 0 :(得分:7)
你很可能是正确的 - 读取那么多文件可能会限制你的潜在加速,因为磁盘I / O将是限制因素。
话虽这么说,你很可能通过将数据处理传递到一个单独的线程来做一点改进。
我建议尝试使用一个读取文件的“生产者”线程。该线程将受IO限制。当它读取文件时,它可以将“处理”推送到ThreadPool线程(.NET 4任务也适用于此),以便进行处理,这将允许它立即读取下一个文件。
这将至少占用整个运行时间的“处理时间”,使得您的工作总时间几乎与磁盘IO一样快,只要您有一两个额外的核心工作...
答案 1 :(得分:2)
我要做的是在一个单独的线程中进行处理。我会在一个文件中读取并将数据存储在队列中,然后读入下一个文件,等等。
在第二个线程中,让线程从该队列中读取数据并进行处理。看看是否有帮助!
答案 2 :(得分:0)
可能是磁盘搜索时间,这是限制因素(这是做Make时最常见的瓶颈之一,通常涉及大量小文件)。哑文件系统设计有一个目录条目,并且坚持指向文件的磁盘块的指针,并且每个文件至少需要1次搜索。
如果您使用的是Windows,我将切换到使用NTFS(将存储在目录条目中的小文件( - >为每个文件保存一个磁盘搜索)。我们使用磁盘压缩, (计算更多,但CPU便宜且快速,但磁盘空间更少 - >读取时间更短);如果您的文件都很小,这可能不相关。可能有一个Linux文件系统等效,如果你在哪里
是的,您应该启动一堆线程来读取文件:
forall filename in list: fork( open filename, process file, close filename)
您可能需要对此进行限制以防止线程耗尽,但我会拍摄数百个而不是2或3.如果您这样做,则告诉操作系统它可以读取磁盘上的许多位置,它可以通过磁盘放置来排序多个请求 (elevator algorithm),这也有助于减少头部运动。
答案 3 :(得分:0)
我建议使用“MultiThreading”来解决这个问题。当我读到你的帖子答案时,突然发现Reed Copsey的答案会非常有成效。您可以在此Elmue上找到由link准备的此解决方案的示例。我希望这可以有用,感谢Reed Copsey。 此致
答案 4 :(得分:0)
我同意里德和冰人的评论。另外,考虑如何增加磁盘IO。例如,将文件分布在多个磁盘上,以便可以并行读取它们并使用速度更快的磁盘,如SSD或RAM磁盘。