Como ler todas as linhas de um arquivo em paralelo no Java 8
Quero ler todas as linhas de um arquivo grande de 1 GB o mais rápido possível em umStream<String>
. Atualmente estou usandoFiles(path).lines()
por isso. Depois de analisar o arquivo, estou fazendo alguns cálculos (map()
/filter()
) No começo, pensei que isso já fosse feito em paralelo, mas parece que estou errado: ao ler o arquivo, ele leva cerca de 50 segundos no meu laptop com CPU dupla. No entanto, se eu dividir o arquivo usando os comandos bash e depois processá-los em paralelo, leva apenas 30 segundos.
Eu tentei as seguintes combinações:
arquivo único, sem fluxo de linhas paralelas () ~ 50 segundosúnico arquivo,Files(..).lines().parallel().[...]
~ 50 segundosdois arquivos, sem linhas paralelas () strean ~ 30 segundosdois arquivosFiles(..).lines().parallel().[...]
~ 30 segundosEu executei essas 4 várias vezes com aproximadamente os mesmos resultados (em 1 ou 2 segundos). o[...]
é apenas uma cadeia de mapas e filtros, com umtoArray(...)
no final para acionar a avaliação.
A conclusão é que não há diferença no uso delines().parallel()
. Como a leitura de dois arquivos em paralelo leva um tempo menor, há um ganho de desempenho ao dividir o arquivo. No entanto, parece que o arquivo inteiro é lido em série.
Editar: Quero ressaltar que eu uso um SSD, então praticamente não há tempo para procurar tempo. O arquivo possui 1658652 (relativamente curtas) linhas no total. A divisão do arquivo no bash leva cerca de 1,5 segundos:time split -l 829326 file # 829326 = 1658652 / 2 split -l 829326 file 0,14s user 1,41s system 16% cpu 9,560 total
Então, minha pergunta é: existe alguma classe ou função no Java 8 JDK que possa paralelizar a leitura de todas as linhas sem ter que dividir primeiro? Por exemplo, se eu tiver dois núcleos de CPU, o leitor de primeira linha deve começar na primeira linha e o segundo na linha(totalLines/2)+1
.