2010-01-07 47 views
0

我通過fwrite將一些二進制數據寫入二進制文件,一旦我通過寫入,我正在讀取相同的數據,通過fread.While這樣做,我發現fwrite花費更少的時間來寫入整個數據,因爲fread需要更多時間來讀取所有數據。 所以,我只想知道它是否總是花費比fread更少的時間,或者我的閱讀部分有問題。使用二進制文件執行fread/fwrite時的性能

+0

爲什麼這會得到downvoted?似乎是一個合理的問題。 – 2010-01-07 12:18:54

回答

3

C++語言對這些(或任何其他)函數的比較性能不作任何保證。這完全取決於硬件和操作系統的組合,機器上的負載和月球的相位。

+2

同意。在你和硬件之間有一整套圖層,並且經常在內存中緩衝數據,所以不可能概括這個 – zebrabox 2010-01-07 12:11:19

+0

完全正確。但沒有提供任何合理的解釋(或潛在原因)的原因。如果我們期望別人提高你至少需要提及那些可能會減緩進程速度的部分,那麼他們可以做更多的研究(例如其他三個答案中提到的OS IO緩存機制)。 – 2010-01-07 17:43:07

+0

@Martin像往常一樣,我們不同意如何回答SO問題。但你以你的方式去做,我會繼續做我的。 – 2010-01-07 17:53:26

1

正如其他人所說的那樣,您看到緩衝區/緩存系統的某些效果,但是,如果您使用異步API(如您所說的起訴fread/write,請查看aio_read/aio_write),您可以嘗試其他一些I/O方法可能更適合你的工作。

一個建議是,如果您讀取/更新/寫入/讀取文件很多,您應該通過ioctl或DeviceIOControl向操作系統請求以提供代碼運行的磁盤的幾何形狀然後確定磁盤細分器的大小,以便您可以確定是否可以在單個磁盤內緩衝讀/寫操作。這樣,驅動器頭就不會移動以進行讀/寫操作,併爲您節省大量運行時間。

2

這些函數與操作系統的文件系統緩存進行交互。在很多情況下,它是一個簡單的內存到內存的拷貝。如果您重複運行程序,寫入的速度確實會稍微快一點。它只需要在緩存中找到一個空洞來轉儲它的數據。將數據刷新到磁盤發生在您無法看到或測量的時間。

通常需要更多的工作來閱讀。至少需要遍歷緩存結構以發現磁盤數據是否已被緩存。如果沒有,它將不得不阻止磁盤驅動程序請求以從磁盤中檢索數據,這需要幾毫秒。

分析此行爲的標準陷阱是從您的程序的重複運行中進行測量。它們完全不代表你的程序在野外會表現得那麼好。磁盤數據已緩存的可能性爲非常適合在您的程序的第二次運行中使用。他們在現實生活中非常貧窮,讀數可能非常緩慢,尤其是第一個。一個寫入存在額外的特殊陷阱,在某些時候(取決於其他程序的行爲),緩存將無法緩衝寫入請求。隨着程序被阻塞,直到有足夠的數據刷新到磁盤,寫入性能纔會崩潰。

長話短說:不要有史以來假定磁盤讀/寫性能測量代表了您的程序在生產中的表現。也許更重要的是:在代碼中解決磁盤I/O性能問題沒有任何可以做的。

4

雖然正如其他人所說,沒有保證,但您通常會發現單次寫入會比單次讀取更快。寫入操作可能會將數據複製到緩衝區中並立即返回,而讀取操作可能會等待數據從存儲設備中讀取。有時如果緩衝區填滿,寫入會很慢;有時如果數據已被提取,讀取將會很快。有時候,fread/fwrite與存儲硬件之間的許多抽象層之一將決定無緣無故地進入自己的小世界。