2011-10-10 191 views
5

與一次讀取整個文件相比,逐行讀取一行時是否存在顯着差異(理論上)?一次一行讀取文件時的性能vs讀取整個文件

讀取整個文件確實會對使用的內存量產生負面影響,但它的運行速度會更快嗎?

我需要讀取一個文件並處理每一行。我不知道是否應該一次讀一行並處理它,或者讀取整個文件,處理所有文件,然後寫入輸出。

我已經設置了prgm逐行讀取,我想知道是否值得努力將其更改爲讀取整個文件(不容易給出我的設置)。

感謝,

+1

從理論上講,驅動器可能不得不逐行尋找和閱讀更多的程序,具體取決於發生了什麼。實際上,這可能不是問題,因爲緩衝的文件I/O可能被用於讀取較大的塊。您的里程將根據您的硬件和算法的細節而有所不同。在進行優化時,您必須期望編寫多個程序迭代,並添加計時器代碼或使用分析器來查找哪些時間最長。 – holtavolt

回答

0

說實話,攻讀我的學位期間,而效率後,我來到了這個結論對你的問題:這取決於這個文件要多久被讀取。如果你只讀過一次,那就做完整件事情,因爲那樣只會解放其他任務的過程。 還有一件事要留在你的腦海裏,是文件將在稍後編輯並需要更新(如在讀取更新的部分?)如果是這樣的話,你可能需要設置一個標記來重新調整從哪裏讀取(然後再次多久更新一次?)。但是,如果是一次性工作,那麼只要不需要在文件中創建特定文字的標記就可以繼續閱讀。 希望這有助於。

+0

在任何現代的* nix或windows操作系統中,操作系統都會爲您完成這種操作(緩衝,進程間共享,標記更新)。 –

+0

我同意....有時當人們的效率太嚴重,他們實際上變得更糟!即通過執行/干涉緩衝,在進程之間共享,標記更新。 –

0

將整個文件讀入內存通常不是一個好主意,因爲這些文件可能很大並且可能佔用大量內存,在最壞情況下會導致內存不足。因此,爲了平衡性能和內存使用量,您需要將一個文件塊讀入緩衝區並通過緩衝區進行解析。處理完塊後,讀取下一個塊直到EOF。

決定一個好的塊大小將必須根據你想要達到的目的來完成。

+1

文件系統將爲您執行所有「塊」操作!它的被稱爲緩衝區管理,在OS緩衝之上實現自己的緩衝只會減慢你的速度。 –

+0

@詹姆斯安德森 - 你是對的:)我只是把它作爲OP提到的「理論上」的獨家。 – srikanta

2

讀取整個文件會稍快一些 - 但不會太多!

但是,要小心讀取整個文件不可擴展,因爲受限於系統中的可用內存,一旦文件大小超過了RAM程序的大小,它將開始使用交換空間將會慢得多。如果文件大小超過可用虛擬內存的大小,則程序將崩潰。

0

其中一個因素是您要讀取多少數據,以及程序最初需要運行多長時間,即運行性能是否有任何好處。

請參閱this answer中的書中關於思考軟件性能的一般性建議。

(我知道你在理論上答案,但何時擔心性能這方面也很重要,只要你有一個有限的時間支出金額)。

1

與其他人一樣,我相信做更大的讀取會提高你的應用程序的性能,但不要期待奇蹟,I/O已經在操作系統層被緩衝了,所以你只能通過減少有太多讀取調用的開銷來獲得。一次讀取整個文件是危險的,除非您知道輸入文件的最大可能大小。最合理的方法是以大塊讀取文件。

如果您想進一步改進,您應該考慮將I/O與處理重疊。假設您以128MB的塊讀取輸入文件。在您的主線程上,您讀取第一個128MB的塊,然後將其傳遞給工作線程進行處理。當工作線程開始工作時,主線程讀取第二個128MB的數據塊。從那時起,當工作者線程正在處理塊N時,主線程正在從磁盤讀取塊N + 1。

0

我認爲這將取決於您的應用程序的需求(就像我知道的大多數事情一樣)。讀取節點js中的1 MB文件的速度比使用可讀流或線性閱讀器的fs.readFile()快3-4倍,只要讀取文件即可。如果文件非常大並且您正在處理輸入,則流可能會提供一些額外的性能。如果你的應用程序已經佔用了大量內存,那麼它也可能是理想的,因爲Node進程在64位系統上的內存限制約爲1.5GB。如果數據源相對於cpu可以處理它的速度較慢(在HDD或磁帶上歸檔,像TCP這樣的網絡連接),那麼處理數據塊時它們也可能更具性能。至於將文件讀入內存或將其傳輸到內存中,我猜測發送數據事件的函數調用開銷和切換到處理函數回調會減慢進程。