2009-01-05 4 views
6

Estoy tratando de determinar cuál es la manera más rápida de leer en archivos de texto grandes con muchas filas, hacer algunos procesamientos y escribirlos en un archivo nuevo. En C# /. Net, parece que StreamReader es una forma aparentemente rápida de hacerlo, pero cuando intento usarlo para este archivo (leyendo línea por línea), va aproximadamente 1/3 de la velocidad de E/S de python (lo cual me preocupa) porque sigo oyendo que el IO de Python 2.6 fue relativamente lento).¿Cuál es la forma óptima (velocidad) de analizar un archivo de texto grande (> 4 GB) con muchas (miliones) de líneas?

Si no hay una solución .Net más rápida para esto, ¿sería posible escribir una solución más rápido que StreamReader o ya utiliza un búfer/algoritmo/optimizaciones complicados que nunca esperaría superar?

+0

Una pregunta, ¿dónde está su cuello de botella en el código C#? ¿Ha perfilado o medido el código? 1/3 de la velocidad de Python no parece adecuado para operaciones que implican un acceso de disco pesado. –

+0

cada obtener una respuesta válida en este caso? ¿Estabas leyendo el EOF o cuál era tu estrategia con el lector de flujo? –

Respuesta

2

StreamReader es bastante bueno. ¿Cómo lo leía en Python? Es posible que si especifica una codificación más simple (por ejemplo, ASCII), eso acelere las cosas. ¿Cuánta CPU está tomando el proceso?

Puede aumentar el tamaño del búfer utilizando el constructor de StreamReader apropiado, pero no tengo idea de la diferencia que es probable que haga.

+0

Supongo que aumentar el tamaño del búfer de su StreamWriter (presumiblemente él está usando uno) sería una gran diferencia. –

3

¿Tiene un ejemplo de código de lo que hace, o el formato del archivo que está leyendo?

Otra buena pregunta sería ¿qué parte de la secuencia está guardando en la memoria a la vez?

0

Una nota general:

  1. transmisión de alto rendimiento no es complicado. Por lo general, debe modificar la lógica que utiliza los datos transmitidos; eso es complicado.

En realidad, eso es todo.

0

Disculpe si no soy un gurú de .NET, pero en C/C++, si tiene buenos búfers grandes, debería ser capaz de analizarlos con un analizador LL1 no mucho más lento de lo que puede escanear los bytes. Puedo dar más detalles si quieres.

0

Pruebe BufferedReader y BufferedWriter para acelerar el procesamiento.

+0

Creo que son clases de Java. StreamReader para .Net ya está almacenado. – GvS

+0

Sí, esas son de hecho clases de Java, él está buscando una solución en C#. Si fuera Java, recomendaría lo mismo. –

0

Los tamaños de búfer predeterminados utilizados por StreamReader/FileStream pueden no ser óptimos para las longitudes de registro en sus datos, por lo que puede intentar ajustarlos. Puede anular las longitudes predeterminadas del búfer en los constructores tanto para FileStream como para el StreamReader que lo envuelve. Probablemente deberías hacerlos del mismo tamaño.

2

Si su propio código está examinando un carácter a la vez, usted quiera usar un centinela para marcar el final de un tampón o al final del archivo, por lo que tiene una sola prueba en su bucle interno . En su caso, una prueba será para el final de la línea, por lo que querrá pegar temporalmente una nueva línea al final de cada búfer, por ejemplo.

El artículo de Wikipedia sobre centinelas no es útil en absoluto; no describe este caso. Puede encontrar una descripción en cualquiera de los libros de texto de algoritmos de Robert Sedgewick.

Es posible que también desee mirar re2c, que puede generar código muy rápido para escanear datos de texto. Genera código C, pero es posible que pueda adaptarlo, y ciertamente puede aprender las técnicas leyendo su artículo sobre re2c.

Cuestiones relacionadas