Il seguente frammento di codice fa parte di un metodo che ottiene un elenco di directory, chiama un metodo di estrazione su ciascun file e serializza l'oggetto farmaco risultante in xml.Perché lo streaming parallelo di Files.list() è molto più lento rispetto all'utilizzo di Collection.parallelStream()?
try(Stream<Path> paths = Files.list(infoDir)) {
paths
.parallel()
.map(this::extract)
.forEachOrdered(drug -> {
try {
marshaller.write(drug);
} catch (JAXBException ex) {
ex.printStackTrace();
}
});
}
Qui è lo stesso codice esatto facendo la stessa identica cosa, ma utilizzando una pianura .list()
chiamata per ottenere l'elenco di directory e chiamando .parallelStream()
sulla lista risultante.
La mia macchina è un MacBook Pro quad core, Java v 1.8.0_60 (build 1.8.0_60-b27).
Sto elaborando ~ 7000 file. Le medie di 3 serie:
Prima versione: Con .parallel()
: 20 secondi. Senza .parallel()
: 41 secondi
Seconda versione: Con .parallelStream()
: 12 secondi. Con .stream()
: 41 secondi.
Questi 8 secondi in modalità parallela sembrano un'enorme differenza dato che il metodo extract
che legge dallo streaming e fa tutto il lavoro pesante e la chiamata write
alle scritture finali sono invariate.
come funziona il tuo codice senza parallelStream? – sidgate
Dubito che File.list() sia "lo stesso identico codice che fa la stessa identica cosa" che attraversa un DirectoryStream. – VGR
@sidgate Ho aggiornato la domanda. Senza parallelizzazione vengono eseguite quasi esattamente nello stesso tempo. – kliron