2012-03-09 2 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 Мб +) Я был в шоке, что эта функция была безусловно, является наихудшим узким местом во всей программе:

Строковый поток, который я использую для анализа строки, использует почти 70% от общей продолжительности выполнения, а команда getline - 25%. Остальная часть программы использует только 5%.

Есть ли быстрый способ прочитать эти большие файлы, возможно, избегая медленных строк и функции getline?

+0

Вы считали boost :: spirit? – je4d

+0

Я хочу избежать повышения, если это возможно. – Listing

+1

долларов в doughtnuts, что ваша библиотека C библиотеки scanf может побить все это. :) – Kaz

ответ

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

1

mmap файл и обрабатывать его как один большой буфер.

Если система испытывает недостаток ММАПА, вы можете попытаться read файл в буфер, который вы malloc

Обоснование: большая часть времени находится в переходе от пользователя к системе и обратно в вызовах библиотеки C , Чтение во всем файле исключает почти все эти вызовы.

+0

Спасибо, я попробую это и сообщит свои результаты. Однако одним из основных узких мест является разбор по строкам, которые не будут удалены, просто прочитав все в огромном буфере. – Listing

Смежные вопросы