Por que o fluxo paralelo Files.list () está executando muito mais lentamente do que usando Collection.parallelStream ()?
O fragmento de código a seguir faz parte de um método que obtém uma listagem de diretório, chama um método de extração em cada arquivo e serializa o objeto de droga resultante para xml.
try(Stream<Path> paths = Files.list(infoDir)) {
paths
.parallel()
.map(this::extract)
.forEachOrdered(drug -> {
try {
marshaller.write(drug);
} catch (JAXBException ex) {
ex.printStackTrace();
}
});
}
Aqui está exatamente o mesmo código, fazendo exatamente a mesma coisa, mas usando um simples.list()
ligue para obter a listagem e a chamada do diretório.parallelStream()
na lista resultante.
Arrays.asList(infoDir.toFile().list())
.parallelStream()
.map(f -> infoDir.resolve(f))
.map(this::extract)
.forEachOrdered(drug -> {
try {
marshaller.write(drug);
} catch (JAXBException ex) {
ex.printStackTrace();
}
});
Minha máquina é um MacBook Pro quad core, Java v 1.8.0_60 (compilação 1.8.0_60-b27).
Estou processando ~ 7000 arquivos. As médias de 3 execuções:
Primeira versão: Com.parallel()
: 20 segundos. Sem.parallel()
: 41 segundos
Segunda versão: Com.parallelStream()
: 12 segundos. Com.stream()
: 41 segundos.
Esses 8 segundos no modo paralelo parecem uma enorme diferença, uma vez que oextract
método que lê a partir do fluxo e faz todo o trabalho pesado e owrite
a chamada que realiza as gravações finais permanece inalterada.