JDK8-Stream并行流详解

1、并行与并发的区别

在说到并行的时候,相信很多人都会想到并发的概念。那么并行和并发两者一字之差,有什么区别呢?

并行:多个任务在同一时间点发生,并由不同的cpu进行处理,不互相抢占资源

并行:

JDK8-Stream并行流详解

并发:多个任务在同一时间点内同时发生了,但由同一个cpu进行处理,互相抢占资源

并发:

JDK8-Stream并行流详解

当在大量数据处理上,数据并行化可以大量缩短任务的执行时间,将一个数据分解成多个部分,然后并行处理,最 后将多个结果汇总,得到最终结果。

2、并行流原理介绍

对于并行流,其在底层实现中,是沿用了Java7提供的fork/join分解合并框架进行实现。fork根据cpu核数进行数 据分块,join对各个fork进行合并。实现过程如下所示:

JDK8-Stream并行流详解

3、影响并行流性能主要存在5个因素

对于并行流,一定不要陷入一个误区:并行一定比串行快。并行在不同的情况下它不一定是比串行快的。影响并行 流性能主要存在5个因素:

1)数据大小:输入数据的大小,直接影响了并行处理的性能。因为在并行内部实现中涉及到了fork/join操作,它 本身就存在性能上的开销。因此只有当数据量很大,使用并行处理才有意义。

2)源数据结构:fork时会对源数据进行分割,数据源的特性直接影响了fork的性能。 ArrayList、数组或IntStream.range,可分解性最佳,因为他们都支持随机读取,因此可以被任意分割。 HashSet、TreeSet,可分解性一般,其虽然可被分解,但因为其内部数据结构,很难被平均分解。 LinkedList、Streams.iterate、BufferedReader.lines,可分解性极差,因为他们长度未知,无法确定在哪里进行 分割。

3)装箱拆箱 尽量使用基本数据类型,避免装箱拆箱。

4)CPU核数 fork的产生数量是与可用CPU核数相关,可用的核数越多,获取的性能提升就会越大。

5)单元处理开销 花在流中每个元素的时间越长,并行操作带来的性能提升就会越明显。

4、测试总结

1)基本类型

性能消耗: Stream串行>for循环>Stream并行

2)对象

性能消耗:Stream串行>for循环>Stream并行

3)复杂对象

性能消耗:for循环>Stream串行>Stream并行

结论:对于简单操作,如果环境机是多核的话,建议使用Stream并行,同时在不考虑核数的情况 下,普通for循环性能要明显高于Stream串行,相差两倍左右。 对于复杂操作,推荐使用Stream API操作。

发表评论

评论已关闭。

相关文章