2011-08-23 133 views
6

我正在嘗試將c#程序遷移到C++。 c#程序逐行讀取一個1〜5 gb大小的文本文件,並對每行進行一些分析。這個C#代碼如下所示。C++文本文件讀取性能

using (var f = File.OpenRead(fname)) 
using (var reader = new StreamReader(f)) 
    while (!reader.EndOfStream) { 
     var line = reader.ReadLine(); 
     // do some analysis 
    } 

對於具有700萬行的給定1.6 gb文件,此代碼大約需要18秒。

C++代碼我寫第一遷移是像下面

ifstream f(fname); 
string line;  
while (getline(f, line)) { 
    // do some analysis 
} 

C++代碼以上需要約420秒。我寫的第二個C++代碼如下所示。

ifstream f(fname); 
char line[2000]; 
while (f.getline(line, 2000)) { 
    // do some analysis 
} 

上面的C++大約需要85秒。

我試過的最後一個代碼是c代碼,如下所示。

FILE *file = fopen (fname, "r"); 
char line[2000]; 
while (fgets(line, 2000, file) != NULL) { 
    // do some analysis 
} 
fclose (file); 

上面的c代碼大約需要33秒。

將最後2個代碼解析爲char []而不是字符串的代碼都需要大約30秒的時間才能將char []轉換爲字符串。

有沒有一種方法可以提高c/C++代碼的性能來逐行讀取文本文件以匹配c#的性能? (補充:我使用Windows用VC++ 10.0 7 64位操作系統,64位)

+0

你的問題是類似於這個線程http://stackoverflow.com/questions/7102087/how-to-enhance-the-speed-of-my-c-program-in-reading-delimited-text-files/ 7102179#7102179 –

+1

一個有趣的問題是:C#如何做到這一點?這會給你一些關於他們使用什麼優化的信息,並可能提供一些信息。 – ssube

回答

9

之一,以提高文件讀取性能的最佳方法之一是使用內存映射文件(mmap()在Unix,Windows上CreateFileMapping()等)。然後你的文件作爲一個平坦的字節塊出現在內存中,你可以比緩衝I/O更快地讀取它。

對於大於千兆字節左右的文件,您將希望使用64位操作系統(使用64位進程)。我已經完成了這項工作,以Python的方式處理30 GB文件,並獲得了很好的結果

0

我建議兩兩件事:

使用f.rdbuf()->pubsetbuf(...)設置一個更大的讀取緩衝區。我注意到當使用更大的緩衝區大小時,fstream性能有了非常顯着的增長。

而不是getline(...)使用read(...)來讀取較大的數據塊並手動解析它們。

0

編譯優化。 C++有相當一些優化器將刪除的理論開銷。例如。許多簡單的字符串方法將被內聯。這可能就是爲什麼你的char[2000]版本更快。