Строковое чтение файла в C ++ может быть выполнено несколькими различными способами.
[Fast] Цикл с std :: getline ()
Самый простой подход - открыть цикл std :: ifstream с использованием вызовов std :: getline (). Код чистый и понятный.
#include <fstream>
std::ifstream file(FILENAME);
if (file.is_open()) {
std::string line;
while (getline(file, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
file.close();
}
[Fast] Использовать Boost's file_description_source
Другая возможность - использовать библиотеку Boost, но код становится немного более подробным. Производительность очень похожа на приведенный выше код (цикл с std :: getline ()).
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <fcntl.h>
namespace io = boost::iostreams;
void readLineByLineBoost() {
int fdr = open(FILENAME, O_RDONLY);
if (fdr >= 0) {
io::file_descriptor_source fdDevice(fdr, io::file_descriptor_flags::close_handle);
io::stream <io::file_descriptor_source> in(fdDevice);
if (fdDevice.is_open()) {
std::string line;
while (std::getline(in, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
fdDevice.close();
}
}
}
[Самый быстрый] Использовать код C
Если производительность важна для вашего программного обеспечения, вы можете рассмотреть возможность использования языка Си. Этот код может быть в 4-5 раз быстрее, чем версии C ++ выше, см. Тест ниже
FILE* fp = fopen(FILENAME, "r");
if (fp == NULL)
exit(EXIT_FAILURE);
char* line = NULL;
size_t len = 0;
while ((getline(&line, &len, fp)) != -1) {
// using printf() in all tests for consistency
printf("%s", line);
}
fclose(fp);
if (line)
free(line);
Тест - Какой из них быстрее?
Я сделал несколько тестов производительности с кодом выше, и результаты интересны. Я проверил код с файлами ASCII, которые содержат 100 000 строк, 1 000 000 строк и 10 000 000 строк текста. Каждая строка текста содержит в среднем 10 слов. Программа скомпилирована с оптимизацией -O3
, и ее выходные данные передаются в /dev/null
, чтобы удалить переменную времени регистрации из измерения. И наконец, что не менее важно, каждый фрагмент кода регистрирует каждую строку с помощью функции printf()
для согласованности.
Результаты показывают время (в мс), которое потребовалось каждому фрагменту кода для чтения файлов.
Разница в производительности между двумя подходами C ++ минимальна и не должна иметь никакого значения на практике. Производительность кода C - это то, что делает эталон впечатляющим и может повлиять на скорость игры.
10K lines 100K lines 1000K lines
Loop with std::getline() 105ms 894ms 9773ms
Boost code 106ms 968ms 9561ms
C code 23ms 243ms 2397ms