我有大量(>100k)相对较小(1kb - 300kb)的文件需要读入和处理。我目前正在遍历所有文件,并使用File.ReadAllText读取内容、处理内容,然后读取下一个文件。这是相当慢的,我想知道是否有一个好的方法来优化它。
我已经尝试使用多个线程,但由于这似乎是IO限制的,我没有看到任何改进。
发布于 2010-07-09 00:38:25
您很可能是正确的-读取太多文件可能会限制您潜在的加速,因为磁盘I/O将是限制因素。
也就是说,您很可能可以通过将数据的处理传递到单独的线程中来做一些小的改进。
我建议尝试使用一个“生产者”线程来读取文件。此线程将受到IO限制。当它读取一个文件时,它可以将“处理”推入一个ThreadPool线程(.NET 4任务在这方面也很好用),以便进行处理,这将允许它立即读取下一个文件。
这至少会将“处理时间”从总运行时间中去掉,使作业的总时间几乎与磁盘IO一样快,前提是您有一个或两个额外的内核可用……
发布于 2010-07-09 00:39:11
我要做的是在一个单独的线程中进行处理。我会读入一个文件并将数据存储在队列中,然后读入下一个文件,依此类推。
在第二个线程中,让线程从队列中读取数据并对其进行处理。看看这是否有帮助!
发布于 2010-07-09 00:52:00
这可能是磁盘寻道时间的限制因素(这是执行Make时最常见的瓶颈之一,通常涉及许多小文件)。哑巴文件系统设计有一个目录项,并坚持指向文件的磁盘块的指针,这保证了每个文件至少有1个寻道。
如果您使用的是Windows,我会切换到使用NTFS (它将小文件存储在目录条目中(-->为每个文件保存一个磁盘寻道)。我们也使用磁盘压缩(计算量更大,但是CPU更便宜,速度更快,但是磁盘空间更少-->读取时间更少);如果您的文件都很小,这可能无关紧要。如果您所在的位置是Linux文件系统,那么可能会有一个与之等效的文件系统。
是的,你应该启动一堆线程来读取文件:
forall filename in list: fork( open filename, process file, close filename)你可能不得不限制线程,以防止线程耗尽,但我会选择数百个线程,而不是2或3个。如果你这样做,你就会告诉操作系统它可以读取磁盘上的许多位置,并且它可以按磁盘位置(elevator algorithm)对多个请求进行排序,这也将有助于最小化磁头运动。
https://stackoverflow.com/questions/3205898
复制相似问题