2012-03-09 102 views
3

我正在寫圖形庫,應該讀取最常見的圖形格式。一種格式包含這樣的信息:解析文件的快速方法?

e 4 3 
e 2 2 
e 6 2 
e 3 2 
e 1 2 
.... 

我想解析這些行。我查看了一下stackoverflow,並找到neat solution來做到這一點。我目前使用這樣的方法(文件是fstream的):

string line; 
while(getline(file, line)) { 
    if(!line.length()) continue; //skip empty lines 
    stringstream parseline = stringstream(line); 
    char identifier; 
    parseline >> identifier; //Lese das erste zeichen 
    if(identifier == 'e') { 
     int n, m; 
     parseline >> n; 
     parseline >> m; 
     foo(n,m) //Here i handle the input 
    } 
} 

它的工作原理相當不錯,如預期,但今天當我巨大的圖形文件進行了測試(50 MB +),我感到非常震驚,這個功能是到目前爲止是整個程序中最糟糕的瓶頸:

我用來分析該行的stringstream佔總運行時間的近70%,getline命令佔用25%。該計劃的其餘部分僅使用5%。

是否有快速的方式來讀取這些大文件,可能避免慢串流和getline函數?

+0

你認爲boost :: spirit? – je4d 2012-03-09 00:36:01

+0

如果可能,我想避免增加。 – Listing 2012-03-09 00:36:44

+1

美元doughtnuts,您的C庫scanf可以擊敗所有這些。 :) – Kaz 2012-03-09 00:44:15

回答

3

您可以跳過雙緩衝你的字符串,跳過解析單個字符,使用strtoll解析整數,像這樣:

string line; 
while(getline(file, line)) { 
    if(!line.length()) continue; //skip empty lines 
    if (line[0] == 'e') { 
     char *ptr; 
     int n = strtoll(line.c_str()+2, &ptr, 10); 
     int m = strtoll(ptr+1, &ptr, 10); 
     foo(n,m) //Here i handle the input 
    } 
} 

在C++中,strtoll應該在<cstdlib>包含文件。

+0

不錯,我想結合這兩個答案我可以寫很快的東西。 – Listing 2012-03-09 00:46:34

1

mmap該文件並將其作爲單個大緩衝區進行處理。

如果系統缺乏MMAP,你可以嘗試read文件到緩衝區中,你malloc

理由:大部分時間是從用戶到系統早在調用C庫中的過渡。讀取整個文件幾乎可以消除所有這些呼叫。

+0

謝謝,我會試試這個,並報告我的結果。然而,一個主要瓶頸是通過字符串流進行解析,這不會通過讀取巨大緩衝區中的所有內容來刪除。 – Listing 2012-03-09 00:43:35