c++ - usar - ¿Cómo acceder de forma directa y eficiente a archivos de texto muy grandes?
usar archivo txt como base de datos (3)
Algunas otras opciones más allá de lo que se ha mencionado aquí que no requerirán escanear todo el archivo:
realice un proceso maestro que empuje las líneas a través de tuberías / fifos a los procesos secundarios que realizan el procesamiento real. Esto podría ser un poco más lento, pero si el 90% del tiempo empleado en los subprocesos es el procesamiento real de los textos, debería estar bien.
Un truco estúpido pero efectivo: digamos que tiene N procesos, y puede decirle a cada proceso por argv o algo así como "número de serie", por ejemplo,
processor -serial_number [1|2|3...N] -num_procs N
, todos pueden leer los mismos datos, pero procesan solo las líneas que tienenlineno % num_procs == serial_number
. es un poco menos eficiente porque todos leerán los datos completos, pero nuevamente, si solo funcionan en cada línea Nth, y eso es lo que más consume el tiempo, debería estar bien.
Tengo archivos de texto muy grandes (+ 10GB) que quiero leer para algunas técnicas de minería de datos. Para hacer eso, uso técnicas paralelas con MPI, por lo que muchos procesos pueden acceder juntos al mismo archivo.
De hecho, quiero que cada proceso lea N número de líneas. Dado que el archivo no está estructurado (el mismo número de campos pero cada campo puede contener un número diferente de caracteres), tengo la obligación de analizar el archivo y eso no es paralelo y requiere mucho tiempo. ¿Hay alguna forma de acceder directamente a un número específico de líneas analizando y contando las líneas? Gracias por tu ayuda.
No, no hay: hasta que no lea sus datos desconocidos, nadie sabrá cuántos nuevos caracteres de línea hay. La complejidad de este problema es O (n), lo que significa que al menos una vez tendrás que leer el archivo completo. Entonces es posible que desee crear una tabla de índice donde registre dónde hay nuevos caracteres de línea en su archivo: esto puede ser utilizado por todos los procesos y con Fseek puede acelerar considerablemente el acceso adicional.
Si su archivo no está indexado de otra manera, no hay forma directa.
Tal vez valga la pena indexarlo (escanéelo una vez para encontrar todos los finales de línea y almacene las compensaciones de cada línea o parte de las líneas). Si necesita procesar el archivo varias veces y no cambia, el costo de la indexación podría compensarse con la facilidad de uso del índice para ejecuciones adicionales.
De lo contrario, si no necesita que todos los trabajos tengan exactamente el mismo número de líneas / elementos, simplemente puede modificarlos.
Busque un desplazamiento dado (digamos 1G) y busque el separador de línea más cercano. Repita en el desplazamiento 2G, etc. hasta que haya encontrado suficientes puntos de ruptura.
Luego puede iniciar sus tareas paralelas en cada uno de los fragmentos que haya identificado.