如果您将它与多个地图链接起来,我认为它不会做得更好。如果您的代码不是很复杂,我宁愿使用单个大地图。
要理解这一点,我们必须检查map
函数内部的代码。关联
public final <R> Stream<R> map(Function<? super P_OUT, ? extends R> mapper) {
Objects.requireNonNull(mapper);
return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) {
return new Sink.ChainedReference<P_OUT, R>(sink) {
@Override
public void accept(P_OUT u) {
downstream.accept(mapper.apply(u));
}
};
}
};
}
正如你所看到的,很多事情发生在幕后。创建多个对象并调用多个方法。因此,对于每个链接的map
函数调用,所有这些都会重复。
现在回过头来ParallelStreams
,他们研究并行性的概念。
流文档
并行流是将其元素拆分为多个块的流,并使用不同的线程处理每个块。因此,您可以在多核处理器的所有内核上自动划分给定操作的工作负载,并保持所有内核同样繁忙。
Parallel
流在内部使用 default ForkJoinPool
,默认情况下,它的线程数与处理器数一样多,由Runtime.getRuntime().availableProcessors()
. 但是您可以使用系统属性更改此池的大小java.util.concurrent.ForkJoinPool.common.parallelism.
ParallelStream
在集合对象上调用 spliterator() ,该对象返回一个Spliterator实现,该实现提供了拆分任务的逻辑。每个源或集合都有自己的拆分器实现。使用这些拆分器,并行流尽可能长时间地拆分任务,最后当任务变得太小时,它会顺序执行它并合并来自所有子任务的部分结果。
所以我更喜欢parallelStream
什么时候
- 我一次要处理大量数据
- 我有多个核心来处理数据
- 现有实现的性能问题
- 我已经没有运行多线程进程,因为它会增加复杂性。
性能影响
- 开销:有时当数据集很小时,将顺序流转换为并行流会导致性能下降。管理
threads
、来源和结果的开销是比实际工作更昂贵的操作。
- 拆分:
Arrays
可以便宜且均匀地拆分,但LinkedList
没有这些属性。TreeMap
并且HashSet
拆分比数组好,LinkedList
但不如数组好。
- 合并:合并操作对于一些操作来说真的很便宜,比如归约和加法,但是像分组到集合或映射这样的合并操作可能非常昂贵。
结论:大量数据和每个元素完成的许多计算表明并行性可能是一个不错的选择。