Warum arbeitet der parallele Stream Files.list () so viel langsamer als der parallele Stream Collection.parallelStream ()?

Das folgende Codefragment ist Teil einer Methode, die eine Verzeichnisliste abruft, eine Extraktionsmethode für jede Datei aufruft und das resultierende Arzneimittelobjekt in XML serialisiert.

try(Stream<Path> paths = Files.list(infoDir)) {
    paths
        .parallel()
        .map(this::extract)
        .forEachOrdered(drug -> {
            try {
                marshaller.write(drug);
            } catch (JAXBException ex) {
                ex.printStackTrace();
            }
        });
}

Hier ist genau derselbe Code, der genau das Gleiche tut, aber ein einfaches @ verwende.list() call, um die Verzeichnisliste zu erhalten und @ aufzuruf.parallelStream() auf der resultierenden Liste.

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();
    }
});

Meine Maschine ist ein Vierkern-MacBook Pro, Java v 1.8.0_60 (Build 1.8.0_60-b27).

Ich verarbeite ~ 7000 Dateien. Der Durchschnitt von 3 Läufen:

Erste Version: Mit.parallel(): 20 Sekunden. Ohne.parallel(): 41 Sekunden

Zweite Version: Mit.parallelStream(): 12 Sekunden. Mit.stream(): 41 Sekunden.

Diese 8 Sekunden im parallelen Modus scheinen ein enormer Unterschied zu sein, da dasextract -Methode, die aus dem Stream liest und all die schwere Arbeit und das @ erlediwrite Aufruf, der die letzten Schreibvorgänge ausführt, bleibt unverändert.

Antworten auf die Frage(6)

Ihre Antwort auf die Frage