[英]C++: Improving ifstream binary file reading speed
我正在將小型程序從PHP重寫為C ++。 這個想法基本上是讀取SSD上的32Gb文件並對其進行一些簡單的操作。
我將Visual Studio 2012與x64發行版一起使用。 PHP是5.3 32位。
問題在於,PHP的裸讀速度比C ++高,這確實讓我感到困惑。 PHP的速度約為350 Mb / s,C ++ / ifstream的代碼速度為180 Mb / sec。
代碼真的很簡單:
ifstream datafile("data.txt", ios::binary);
while(datafile.read((char*)buffer, data_per_chunk)) {
// do stuff;
我嘗試了高達16Mb的不同大小的緩沖區,但差別不大。 我還嘗試通過datafile.rdbuf()-> pubsetbuf(...)設置內部緩沖區,但也沒有任何區別。
關於如何在不恢復古老的C級界面的情況下加快ifstream速度有任何提示嗎? 我希望至少達到PHP的性能水平。 也許一些花哨的預讀/緩存設置之類的。
我知道內存映射的文件可能會有所幫助,但是如果可以簡化事情,因為文件明顯大於物理RAM且大於4Gb,即可能的32位構建不可行,則我寧願調整ifstream的設置。 。
看來即使使用ifstream也可以達到最大的SSD讀取速度。
為此,您需要將內部ifstream讀緩沖區設置為〜2Mb,這是峰值SSD讀取速度發生的地方,同時恰好適合CPU的二級緩存。 然后,您需要讀取小於內部緩沖區的數據塊。 以8-16kB的塊讀取數據具有最佳結果,但比以1Mb的塊讀取速度僅快約1%。
設置ifstream內部緩沖區:
ifstream datafile("base.txt", ios::binary);
datafile.rdbuf()->pubsetbuf(iobuf, sizeof iobuf);
通過所有這些調整,我獲得了495 Mb / sec的讀取速度,這接近M500 480Gb SSD的理論最大值。 在執行期間,CPU負載為5%,這意味着它實際上不受ifstream實現開銷的限制。
我發現ifstream和std :: basic_filebuf之間沒有明顯的速度差異。
當您將所有內容讀入緩沖區時,我看不到使用ifstream
的意義。 basic_filebuf
或“古代” C接口都將起作用。 您需要先將ifstream
與C接口進行比較,以便您知道真正應歸咎於ifstream
。
我以提高性能的順序看到以下選項:
std::ifstream
: read
等 std::basic_filebuf
: open
, sgetn
等 fopen
, fread
等。 CreateFile
( 不是 OpenFile
!), ReadFileEx
等。 也許PHP不在內部使用C接口,而是在winapi上使用,這就是區別所在。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.