2010-07-08 107 views
7

我有大量(> 100k)相對較小的文件(1kb - 300kb),需要讀入和處理。我正在循環瀏覽所有文件,並使用File.ReadAllText來閱讀內容,處理它,然後閱讀下一個文件。這很慢,我想知道是否有一種優化它的好方法。快速讀取大量文件

我已經嘗試使用多線程,但因爲這似乎是IO綁定我沒有看到任何改進。

+0

什麼部分最長?加載文件或處理它們? – 2010-07-08 16:35:52

+0

@NickLarsen:加載文件。 – Tim 2010-07-08 16:37:49

+0

即使加載時間最長,多線程仍然可以爲您帶來收益,因爲它可以至少從總體運行時中刪除(大部分)處理方面。 – 2010-07-08 16:39:01

回答

7

你很可能是正確的 - 讀取這麼多文件可能會限制你的潛在加速,因爲磁盤I/O將成爲限制因素。這就是說,你很可能可以通過將數據處理傳遞給一個單獨的線程來做一些小的改進。

我會建議試着讓一個「生產者」線程讀取你的文件。此線程將IO限制。當它讀取一個文件時,它可以將「處理」推送到一個ThreadPool線程中(.NET 4的任務也適用於此)以執行處理,這將允許它立即讀取下一個文件。

這將至少從整個運行時間中取出「處理時間」,使得作業的總時間幾乎與磁盤IO一樣快,只要您有一個或兩個額外的核心工作。

+0

哈哈正是我所說的。英雄所見略同 – Icemanind 2010-07-08 16:39:47

2

我會做的是在一個單獨的線程中進行處理。我會讀入一個文件並將數據存儲在隊列中,然後讀入下一個文件,等等。

在第二個線程中,讓線程讀取該隊列中的數據並對其進行處理。看看是否有幫助!

0

這可能是磁盤尋道時間,這是限制因素(這是製作Make時最常見的瓶頸之一,通常涉及大量小文件)。啞文件系統設計有一個目錄項,並且堅持一個指向文件的磁盤塊的指針,並且每個文件至少需要1個搜索。如果你正在使用Windows,我會切換到使用NTFS(它存儲小文件目錄項( - >保存每個文件一個磁盤尋道)。我們也使用磁盤壓縮(更多的計算但是CPU價格便宜而且速度快但磁盤空間少 - >讀取時間少);如果文件都很小,這可能與您的文件不相關,可能有一個Linux文件系統等效,如果這就是您所在的位置。 ,您應該啓動一堆線程來讀取這些文件:

 forall filename in list: fork(open filename, process file, close filename) 

您可能必須加油門以防止ru但是我會拍攝數百個而不是2個或3個。如果你這樣做,你告訴操作系統它可以讀取磁盤上的很多地方,並且它可以通過磁盤佈局來排列多個請求 (elevator algorithm),這也有助於減少頭部運動。

0

我會推薦「MultiThreading」來解決這個問題。當我讀到你的帖子答案時,突然發現裏德科普塞的答案會如此高效。您可以在此link上找到此解決方案的樣本,該樣本由Elmue準備。我希望這可以是有用的,並感謝Reed Copsey。 Regards

0

我同意裏德和冰人的評論。另外,考慮如何增加磁盤IO。例如,將文件分散到多個磁盤上,以便它們可以並行讀取,並使用速度更快的磁盤,例如SSD或RAM磁盤。