Следующий фрагмент кода является частью метода, который получает список каталогов, вызывает метод извлечения для каждого файла и сериализует полученный объект препарата в xml.
try(Stream<Path> paths = Files.list(infoDir)) {
paths
.parallel()
.map(this::extract)
.forEachOrdered(drug -> {
try {
marshaller.write(drug);
} catch (JAXBException ex) {
ex.printStackTrace();
}
});
}
Вот тот же самый код, который делает то же самое, но с помощью простого вызова .list()
для получения списка каталогов и вызова .parallelStream()
в результирующем списке.
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();
}
});
Моя машина - это четырехъядерный MacBook Pro, Java v 1.8.0_60 (build 1.8.0_60-b27).
Я обрабатываю ~ 7000 файлов. Средние из 3 пробегов:
Первая версия:
С .parallel()
: 20 секунд. Без .parallel()
: 41 секунд
Вторая версия:
С .parallelStream()
: 12 секунд. С .stream()
: 41 секунда.
Те 8 секунд в параллельном режиме кажутся огромной разницей, учитывая, что метод extract
, который читает из потока, и делает всю тяжелую работу и вызов write
, выполняющий окончательную запись, не изменяется.