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.

questionAnswers(3)

yourAnswerToTheQuestion