2011-04-18 191 views
4

我很抱歉如果這個問題有點模糊或者很愚蠢,我仍然是一個新手。在C++中改善ifstream的性能

我需要從C++中的Web日誌文件中提取信息。字符串操作相對而言,及時訪問數據不是。 我目前

string str;

ifstream fh("testlog.log",ios::in);

while (getline(fh,str));

做什麼從這裏我得到的字符串中的有用數據。這對於具有100個條目的日誌文件來說工作良好,但是對於具有百萬個條目的日誌文件會永遠佔用。 任何幫助將大大讚賞

+2

只是爲了測試,你可以嘗試使用'fgets'嗎?用'fopen'打開文件,然後用'while(fgets(cstr,256,fp))'來打開文件。告訴我們你的結果是什麼(需要多長時間)。 – nc3b 2011-04-18 21:55:09

+0

您是否已通過簡介查看瓶頸?如果它是磁盤,代碼本身無法解決這個問題。 (如果你的CPU時間不是IO時代的矮小,你可以多線程。) – GManNickG 2011-04-18 22:07:10

回答

1

在這裏,我找到解壓縮文件的最快方法:

std::ifstream file("test.txt", std::ios::in | std::ios::end); 

std::size_t fileSize = file.tellg(); 

std::vector<char> buffer(fileSize); 

file.seekg(0, std::ios::beg); 

file.read(buffer.data(), fileSize); 

std::string str(buffer.begin(), buffer.end()); 

然而,如果你的文件是真有那麼大,我強烈建議你把它處理爲流。 ..

+0

好吧,我所做的就是獲得文件大小,就像你所做的一樣。將值除以2,對於1個動態數組似乎就是對大數。將字符讀成字符串似乎一直在浪費。所以我想我可以嘗試讀取數組中的每一行,而不需要字符串函數的幫助。它看起來有點凌亂 – Jacques 2011-04-19 09:26:00

2

我真的懷疑I/O在這裏比在ifstream更傷害你。您是否檢查過您是否實際受到CPU限制?很可能你有磁盤和緩存局部性問題。

在這種情況下可能沒有太多可以做的事情。

如果它是CPU綁定你有沒有分析CPU時間的去向?

1

在浪費了幾個小時的時間之後,我在Quincy2005而不是Microsoft Visual Studio中編譯了相同的代碼。結果是戲劇性的。從40分鐘的執行時間到1分鐘。通過將文件處理程序的指針傳遞給getline函數,可以在Microsoft Visual Studio中完成一些改進。在基於Linux的系統上,大約需要40秒才能執行。爲了浪費我的時間,我詛咒微軟40分鐘。

+2

什麼是Quincy2005? – 2011-07-15 11:31:11

1

@Errata:

你確定,你的代碼會快於說:

std::ifstream in("test.txt"); 
in.unsetf(std::ios::skipws); 
std::string contents; 
std::copy(
     std::istream_iterator<char>(in), 
     std::istream_iterator<char>(), 
     std::back_inserter(contents)); 

此外,OP要面向行訪問,這將方便地做到:

std::ifstream in("test.txt"); 
in.unsetf(std::ios::skipws); 
size_t count = std::count_if(
     std::istream_iterator<std::string>(in), 
     std::istream_iterator<std::string>(), 
     &is_interesting); 
std::cout << "Interesting log lines: " << count << std::endl; 

當然定義了一個謂詞,例如

static bool is_interesting(const std::string& line) 
{ 
    return std::string::npos != line.find("FATAL"); 
}