производительность чтения текстовых файлов c ++ - PullRequest
6 голосов
/ 23 августа 2011

Я пытаюсь перенести программу c # на c ++. Программа c # читает построчно текстовый файл размером 1 ~ 5 ГБ и выполняет анализ каждой строки. Код c # как ниже.

using (var f = File.OpenRead(fname))
using (var reader = new StreamReader(f))
    while (!reader.EndOfStream) {
        var line = reader.ReadLine();
        // do some analysis
    }

Для данного файла объемом 1,6 ГБ с 7 миллионами строк этот код занимает около 18 секунд.

Код на C ++, который я написал первым для переноса, выглядит следующим образом

ifstream f(fname);
string line;    
while (getline(f, line)) {
    // do some analysis
}

Код C ++ выше занимает около 420 секунд. Второй код C ++, который я написал, похож на ниже.

ifstream f(fname);
char line[2000];
while (f.getline(line, 2000)) {
    // do some analysis
}

C ++ выше занимает около 85 секунд.

Последний код, который я попробовал, это код c, как показано ниже.

FILE *file = fopen ( fname, "r" );
char line[2000];
while (fgets(line, 2000, file) != NULL ) {
    // do some analysis
}
fclose ( file );

Код c, указанный выше, занимает около 33 секунд.

Оба последних 2 кода, которые анализируют строки в char [] вместо string, требуют около 30 секунд больше для преобразования char [] в строку.

Есть ли способ повысить производительность кода на языке c / c ++, чтобы строка за строкой читала текстовый файл в соответствии с производительностью c #? (Добавлено: я использую 64-битную ОС Windows 7 с VC ++ 10.0, x64)

Ответы [ 3 ]

9 голосов
/ 23 августа 2011

Один из лучших способов повысить производительность чтения файлов - это использовать отображенные в память файлы (mmap() в Unix, CreateFileMapping() и т. Д. В Windows). Затем ваш файл появляется в памяти в виде одного фрагмента байтов, и вы можете прочитать его намного быстрее, чем выполнить буферизованный ввод / вывод.

Для файла размером более гигабайта или около того вы захотите использовать 64-битную ОС (с 64-битным процессом). Я сделал это, чтобы обработать 30 ГБ файл в Python с отличными результатами.

0 голосов
/ 23 августа 2011

Компиляция с оптимизацией.В C ++ есть некоторые теоретические издержки, которые оптимизатор удалит.Например, многие простые строковые методы будут встроены.Вероятно, поэтому ваша char[2000] версия быстрее.

0 голосов
/ 23 августа 2011

Я предлагаю две вещи:

Используйте f.rdbuf()->pubsetbuf(...), чтобы установить больший буфер чтения. Я заметил действительно значительное увеличение производительности fstream при использовании буферов большего размера.

Вместо getline(...) используйте read(...) для чтения больших блоков данных и анализа их вручную.

...