Pregunta

Me han informado que mi biblioteca es más lenta de lo que debería ser, del orden de 30 veces más lento al analizar un archivo en particular (archivo de texto, tamaño 326 kb). El usuario sugirió que puede ser que esté usando std :: ifstream (presumiblemente en lugar de FILE ).

Prefiero no volver a escribir a ciegas, así que pensé en comprobar aquí primero, ya que supongo que el cuello de botella está en otra parte. Estoy leyendo carácter por carácter, por lo que las únicas funciones que estoy usando son get () , peek () y tellg () / seekg () .

Update:

Realicé un perfil y obtuve resultados confusos - gprof no parecía pensar que se necesitaba tanto largo. Reescribí el programa para leer el archivo completo en un búfer primero, y se aceleró aproximadamente 100 veces. Creo que el problema puede haber sido el tellg () / seekg () que tardó mucho tiempo, pero es posible que gprof no haya podido verlo por alguna razón. En cualquier caso, ifstream no parece almacenar todo el archivo, incluso para este tamaño.

¿Fue útil?

Solución

No creo que eso haga la diferencia. Especialmente si está leyendo char por char, es probable que la sobrecarga de E / S domine completamente cualquier cosa más. ¿Por qué lees bytes individuales a la vez? ¿Sabes lo extremadamente ineficiente que es?

En un archivo de 326kb, lo más probable es que la solución más rápida sea simplemente leerlo en la memoria a la vez.

La diferencia entre std :: ifstream y los equivalentes en C, es básicamente una llamada de función virtual o dos. Puede hacer una diferencia si se ejecuta unas pocas decenas de millones de veces por segundo, de lo contrario, no será real. La E / S de archivo es generalmente tan lenta que la API utilizada para acceder a ella realmente no importa. Lo que importa mucho más es el patrón de lectura / escritura. Muchas búsquedas son malas, las lecturas / escrituras secuenciales son buenas.

Otros consejos

Debería ser un poco más lento, pero como dijo, podría no ser el cuello de botella. ¿Por qué no perfilas tu programa y ves si ese es el caso?

Creo que es poco probable que su problema se solucione cambiando de fstream a FILE *, por lo general, ambos están protegidos por la biblioteca C. Además, el sistema operativo puede almacenar lecturas en caché (Linux es muy bueno en ese aspecto). Dado el tamaño del archivo al que está accediendo, es muy probable que esté completamente en RAM.

Como PolyThinker dice que su mejor opción es ejecutar su programa a través de un generador de perfiles y determinar dónde está el problema.

También está utilizando seekg / tellg, esto puede causar retrasos notables si su disco está muy fragmentado, porque para leer el archivo por primera vez, el disco debe mover las cabezas a la posición correcta.

Todos los puntos de referencia son malos. Simplemente perfile su código para los datos que espera.

Realicé una comparación de rendimiento de E / S entre Ruby, Python, Perl, C ++ una vez. Para mis datos, versiones de idiomas, etc. La variante de C ++ fue varias veces más lenta (fue una gran sorpresa en ese momento).

Estoy de acuerdo en que debe hacer un perfil. Pero si estás leyendo el archivo de un personaje a la vez, ¿qué tal si creas un archivo mapeado en memoria? De esa manera, puede tratar el archivo como una matriz de caracteres, y el sistema operativo debe encargarse de todo el almacenamiento en búfer de bajo nivel. La solución más simple y probablemente más rápida es una victoria en mi libro. :)

Aquí es un excelente punto de referencia que muestra que, en condiciones extremas, los fstream son bastante lentos ... a menos que:

  1. Utiliza el almacenamiento en búfer (no puedo enfatizarlo lo suficiente)
  2. Usted manipula el búfer usted mismo (es decir, si necesita un rendimiento como OP en la pregunta vinculada), que no es tan diferente del uso de FILE * .

Sin embargo, no debe optimizar prematuramente. Los fstreams son generalmente mejores, y si necesita optimizarlos en el camino, siempre puede hacerlo más tarde con un bajo costo. Para prepararse para lo peor de antemano, sugiero crear un proxy mínimo para fstream ahora para que pueda optimizarlo más tarde, sin necesidad de tocar nada más.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top