Разбор файлов по быстрому пути? - PullRequest
3 голосов
/ 09 марта 2012

Я пишу в библиотеке графов, которая должна читать наиболее распространенные форматы графов.Один формат содержит такую ​​информацию:

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

, и я хочу проанализировать эти строки.Я оглянулся на stackoverflow и смог найти аккуратное решение , чтобы сделать это.В настоящее время я использую такой подход (файл представляет собой 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?

Ответы [ 2 ]

3 голосов
/ 09 марта 2012

Вы можете пропустить двойную буферизацию строки, пропустить синтаксический анализ одного символа и использовать 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>.

1 голос
/ 09 марта 2012

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

Если в вашей системе отсутствует mmap, вы можете попробовать read файл в буфер, который вы malloc

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

...