为什么 Files.list() 并行流的性能比使用 Collection.parallelStream() 慢得多?
以下代码片段是获取目录列表的方法的一部分,在每个文件上调用一个提取方法,并将生成的药物对象序列化为 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(内部版本1.8.0_60-b27)。
我正在处理~7000个文件。3 次运行的平均次数:
第一个版本:20秒。不含 : 41 秒.parallel()
.parallel()
第二版:12秒。与 : 41 秒..parallelStream()
.stream()
并行模式下的这8秒似乎是一个巨大的差异,因为从流中读取并完成所有繁重工作的方法以及执行最终写入的调用保持不变。extract
write