2015-12-25 54 views
1

我有20個文本文件存儲在硬盤上,每個包含數以百萬計的關於教育機構的信息。假設我有一個方法,它將在循環和過程中迭代文本文件。這是最好的方法來完成每個線程的工作文本文件(Factory.startnew())或每道工序每個文本文件(的Process.Start())最好,更快,佔用更少內存的進程或線程?

編輯 我有8GB的內存,8core服務器,所以想到了來處理它們的線程或process.Currently我正在使用過程,而且我現在沒有發現任何瓶頸。但是我使用線程或進程的困境

+0

使用異步等待我的朋友,它會爲你服務。 – loneshark99

+0

線程對於cpu密集型工作是有好處的,任務對於io /網絡相關的東西都很好 – loneshark99

+0

@ loneshark99請詳細說明。我很想聽聽你的想法。 –

回答

4

硬盤的讀取速度很可能是瓶頸這裏。

因此,根據您需要對數據執行的處理,使用多個線程(我肯定不會使用進程)可能會也可能不會有趣。

但是,最重要的將是確保沒有多個線程同時訪問同一個物理磁盤,因爲這會導致放緩,因爲不斷切換和尋找硬盤驅動器磁頭。

我最近做了一些測試,在某些情況下(取決於硬盤和/或電腦)操作系統照顧它,它並沒有太大的區別,但是在另一個組合上,減速可能會達到正常速度的1/10。因此,如果使用多個線程(只有在您的數據處理需要比您的硬盤讀取時間更長的時間時才需要),請確保您在某處鎖定了一個鎖定,以防止多個線程同時從磁盤讀取數據。

你可能也想看看內存映射文件。

編輯

如果您正在使用的緩衝區的工作,你可以啓動一個線程,不斷填補了緩衝區,而另一個線程處理數據。

EDIT2(在回答米奇):

「的進程或線程,這是最好,更快,需要較少的存儲器?」

正如我所說,我不會使用進程(由於額外的開銷)。這留下了線程,或根本沒有線程 - 取決於需要對數據進行的處理量。如果直接從內存緩衝區中讀取數據(而不是使用類似readline的例子,所有投注都將關閉),則可以使用一個或最大值。兩個線程可能是最好的選擇(如果數據處理足夠快 - 測試和計時將需要確定)。

至於速度和內存使用:最好的選擇(對我來說)是內存映射文件(與文件打開只進模式)。這不僅會利用操作系統磁盤高速緩存的效率,而且還會直接訪問內核內存 - 而在使用(用戶)緩衝區時,內存必須從內核複製到用戶空間,這需要時間和使用額外的內存。

IOCP:好的,但取決於線程會問什麼。例如,如果10個線程依次(在不同的文件上)每次要求100kB,則需要10×10ms的搜尋時間,而讀取100Kb將少於1ms。未來請求的查找時間取決於IOCP如何處理緩存,這可能與使用內存映射相同,但我認爲IOCP在這種情況下不會更快。

並使用IOCP,可能也會複製/填充用戶空間緩衝區(並可能難以處理一般)。但是我不得不說,在編寫我的答案時,我想C/C++(使用直接訪問內存緩衝區)只是稍後纔看到它是C#。儘管這些原則保持不變,但在C#中使用IOCP的異步I/O可能有一個簡單的方法。對於速度測試和避免同時讀取:我已經在大文件上通過超過50個線程進行了測試(通過內存映射) - 如果正確完成,則不會丟失讀取速度。另一方面,當發射一些線程並讓他們隨機訪問硬盤時(即使是大塊),在某些情況下,總讀取速度可能會下降到10% - 有時甚至根本不會。相同的PC,其他硬盤,其他結果。

+0

@Micky - 感謝您的意見:)我添加了一些文字到答案。 –

+0

奇妙。感謝您更新Danny +1 – MickyD

相關問題