2011-08-23 19 views
6

Estoy tratando de migrar un programa C# a C++. El programa C# lee un archivo de texto del tamaño de 1 ~ 5 gb línea por línea y realiza algunos análisis en cada línea. El código C# es como a continuación.rendimiento de lectura del archivo de texto C++

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

Para un archivo dado de 1,6 gb con 7 millones de líneas, este código tarda unos 18 segundos.

El código C++ escribí primero a migrar es como debajo

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

El ++ código C por encima de toma alrededor de 420 segundos. El segundo código de C++ que escribí es como a continuación.

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

El C++ anterior tarda unos 85 segundos.

El último código que probé es código c, como a continuación.

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

El código c anterior toma alrededor de 33 segundos.

Los dos últimos códigos, que analizan las líneas en char [] en lugar de cadena, necesitan aproximadamente 30 segundos más para convertir char [] en cadena.

¿Hay alguna forma de mejorar el rendimiento del código c/C++ para leer un archivo de texto línea por línea para que coincida con el rendimiento de C#? (Alta: Estoy ventanas usando OS 7 64 bits con VC++ 10.0, 64)

+0

Tu pregunta es parecida a este hilo http://stackoverflow.com/questions/7102087/how-to-enhance-the-speed-of-my-c-program-in-reading-delimited-text-files/ 7102179 # 7102179 –

+1

Una pregunta interesante sería: ¿cómo lo está haciendo C#? Eso le dará información sobre las optimizaciones que usaron y probablemente sugiera algunas. – ssube

Respuesta

9

Una de las mejores maneras de aumentar el rendimiento de lectura de archivos es utilizar archivos de memoria mapeada (mmap() en Unix, CreateFileMapping() etc en Windows). Luego, su archivo aparece en la memoria como una porción plana de bytes, y puede leerlo mucho más rápido que haciendo E/S en búfer.

Para un archivo de más de un gigabyte, querrá utilizar un sistema operativo de 64 bits (con un proceso de 64 bits). He hecho esto para procesar un archivo de 30 GB en Python con excelentes resultados.

0

que sugieren dos cosas:

Uso f.rdbuf()->pubsetbuf(...) para establecer un búfer de lectura más grande. Me he dado cuenta de algunos aumentos realmente significativos en el rendimiento de fstream al usar tamaños de búfer más grandes.

En lugar de getline(...), utilice read(...) para leer bloques de datos más grandes y analizarlos manualmente.

0

Compilar con optimizaciones. C++ tiene bastante sobrecarga teórica que el optimizador eliminará. P.ej. muchos métodos simples de cadena estarán en línea. Esa es probablemente la razón por la cual su versión char[2000] es más rápida.

Cuestiones relacionadas