2012-03-09 114 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