La lettura di un file riga per riga in C ++ può essere eseguita in diversi modi.
[Fast] Loop con std :: getline ()
L'approccio più semplice è aprire uno std :: ifstream e un loop usando le chiamate std :: getline (). Il codice è pulito e di facile comprensione.
#include <fstream>
std::ifstream file(FILENAME);
if (file.is_open()) {
std::string line;
while (std::getline(file, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
file.close();
}
[Veloce] Usa il file_description_source di Boost
Un'altra possibilità è utilizzare la libreria Boost, ma il codice diventa un po 'più dettagliato. Le prestazioni sono abbastanza simili al codice sopra (Loop con 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();
}
}
}
[Più veloce] Usa il codice C.
Se le prestazioni sono fondamentali per il tuo software, puoi prendere in considerazione l'uso del linguaggio C. Questo codice può essere 4-5 volte più veloce rispetto alle versioni C ++ sopra, vedi benchmark sotto
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);
Indice di riferimento: quale è più veloce?
Ho fatto alcuni benchmark delle prestazioni con il codice sopra e i risultati sono interessanti. Ho testato il codice con file ASCII che contengono 100.000 righe, 1.000.000 di righe e 10.000.000 di righe di testo. Ogni riga di testo contiene in media 10 parole. Il programma viene compilato con l' -O3
ottimizzazione e il suo output viene inoltrato /dev/null
per rimuovere la variabile del tempo di registrazione dalla misurazione. Ultimo, ma non meno importante, ogni pezzo di codice registra ogni riga con la printf()
funzione per coerenza.
I risultati mostrano il tempo (in ms) impiegato da ciascun pezzo di codice per leggere i file.
La differenza di prestazioni tra i due approcci C ++ è minima e non dovrebbe fare alcuna differenza nella pratica. Le prestazioni del codice C sono ciò che rende impressionante il benchmark e può cambiare il gioco in termini di velocità.
10K lines 100K lines 1000K lines
Loop with std::getline() 105ms 894ms 9773ms
Boost code 106ms 968ms 9561ms
C code 23ms 243ms 2397ms