Spring Boot java: Procesar/Comparar líneas de un archivo muy grande.
Tengo esta aplicación en la que proceso un archivo muy grande, extraigo las líneas que tienen los mismos primeros 5 caracteres (a esto lo llamo currentlineId), las uso para crear un objeto y hacer algo con él, por ejemplo, un ejemplo del contenido del archivo:
AZDFS12345678998765432345678
AZDFS09876545432345678987654
AZDFS34568987654567890987654
AZDFS12345670987654345678998
AZDFS12345098734567765123456
// las líneas anteriores tienen los mismos primeros 5 caracteres, crean el objeto Object1.
FGHJUY121324
FGHJUY089909
FGHJUYTTUTUU
// lo mismo para las líneas anteriores, crean el objeto Object2.
NB: las líneas siempre estarán en un orden en el que las líneas con los mismos primeros 5 caracteres siempre estarán juntas (arriba/abajo una de la otra), así que no tendré líneas por todas partes.
Mi código de función actual:
private void processScpFile(File file) {
LOGGER.info("Procesando Archivo: {} ", file.getName());
try (var br = new BufferedReader(new FileReader(file))) {
String currentLine;
String lastLineId = null;
List<string> similarLineIdsList = new ArrayList<>();
while ((currentLine = br.readLine()) != null) {
if (StringUtils.isEmpty(lastLineId)) {
lastLineId = currentLine.substring(0,5);
}
if (lastLineId.equals(currentLine.substring(0,5))) {
similarLineIdsList.add(currentLine);
}
else if (!lastLineId.equals(currentLine.substring(0,5))) {
doSomethinsWithTheList(similarLineIdsList);
similarLineIdsList.clear();
similarLineIdsList.add(currentLine);
lastLineId= currentLine.substring(0,5);
}
}
doSomethinsWithTheList(similarLineIdsList);
}
catch (IOException e) {
LOGGER.error("No se pudo leer el archivo, {}", e.getMessage(), e);
}
}
Ahora esto ha funcionado bien hasta ahora, pero en adelante debo procesar archivos donde por ejemplo tendría más de 100k líneas con los mismos primeros 5 caracteres, lo que hace que este proceso sea muy lento.
Por favor, ¿tienes alguna sugerencia sobre cómo hacer que este proceso sea más rápido? Gracias.
Edit: solo para ser preciso, es la generación de la lista con los mismos primeros 5 caracteres lo que es más lento a medida que aumenta el número de líneas similares.
davy.ai
Una sugerencia para acelerar este proceso sería utilizar el procesamiento paralelo. Puedes dividir el archivo en fragmentos más pequeños y procesar cada fragmento de forma concurrente. Esto se puede lograr utilizando el API de Stream de Java 8 y su función paralela.
Aquí tienes un ejemplo de código que utiliza streams paralelos para procesar el archivo:
En este código, utilizamos el método
lines()
del BufferedReader para obtener un stream de líneas del archivo. Luego habilitamos el procesamiento paralelo utilizando el métodoparallel()
. Agrupamos las líneas en función de sus primeros 5 caracteres utilizando el recolectorgroupingBy()
, que devuelve un mapa donde las claves son los primeros 5 caracteres y los valores son listas de líneas con la misma clave.A continuación, utilizamos el método
values()
del mapa para obtener un stream de las listas y habilitamos el procesamiento paralelo en ellas utilizandoparallelStream()
. Pasamos cada lista al métododoSomethingWithTheList()
para procesarla.Ten en cuenta que el procesamiento paralelo funciona mejor cuando la operación de procesamiento está limitada por la CPU y no implica llamadas de entrada/salida o de red. Si el método
doSomethingWithTheList()
implica llamadas de entrada/salida o de red, es posible que no veas una mejora significativa en el rendimiento con el procesamiento paralelo.