读Java8函数式编程笔记05_数据并行化

1.并发

1.1.两个任务共享时间段

1.2.一个程序要运行两个任务,并且只有一个CPU给它们分配了不同的时间片,那么这就是并发,而不是并行

2.并行

2.1.两个任务在同一时间发生

2.2.为缩短任务执行时间,将一个任务分解成几部分,然后并行执行

2.3.和顺序执行的任务量是一样的,区别就像用更多的马来拉车,花费的时间自然减少了

2.4.重要

2.4.1.不能再依赖提升CPU的时钟频率来提高现有代码的计算能力

2.4.2.需要利用现代CPU的架构,而这唯一的办法就是编写并行化的代码

2.4.3.阿姆达尔定律

2.4.3.1.一个简单规则,预测了搭载多核处理器的机器提升程序速度的理论最大值

2.5.优化任何和计算相关的任务立即变成了如何有效利用现有硬件的问题

3.数据并行化

3.1.将数据分成块,为每块数据分配单独的处理单元

3.2.把工作拆分,同时在多核CPU上执行的方式

3.3.调用parallel或者parallelStream方法实现数据并行化操作

4.任务并行化

4.1.线程不同,工作各异

4.2.Java EE应用容器

5.并行化流操作

5.1.在一个四核电脑上

5.1.1.10张专辑

5.1.1.1.串行化代码的速度是并行化代码速度的8倍

5.1.2.100张专辑

5.1.2.1.串行化和并行化速度相当

5.1.3.10000张专辑

5.1.3.1.并行化代码的速度是串行化代码速度的2.5倍

5.2.速度提升的因素

5.2.1.输入流的大小

5.2.2.编写代码的方式

5.2.3.核的数量

5.3.底层

5.3.1.并行流还是沿用了fork/join框架

5.3.1.1.fork递归式地分解问题,然后每段并行执行

5.3.1.2.最终由join合并结果,返回最后的值

6.模拟系统

6.1.使用简单操作处理大量数据

6.2.蒙特卡洛模拟法

6.2.1.用在工程、金融和科学计算领域

7.限制

7.1.代码写得符合约定

7.2.初值必须为组合函数的恒等值

7.2.1.求和操作初值必须为0,因为任何数字加0,值不变

7.3.组合操作必须符合结合律

7.3.1.只要序列的值不变,组合操作的顺序不重要

7.4.parallel

7.5.sequential

7.6.最后调用的那个方法起效

8.性能

8.1.数据大小

8.1.1.只有数据足够大、每个数据处理管道花费的时间足够多时,并行化处理才有意义

8.2.源数据结构

8.2.1.每个管道的操作都基于一些初始数据源,通常是集合

8.2.2.将不同的数据源分割相对容易

8.3.装箱

8.3.1.处理基本类型比处理装箱类型要快

8.4.核的数量

8.4.1.核越多,获得潜在性能提升的幅度就越大

8.4.2.核的数量不单指你的机器上有多少核,更是指运行时你的机器能使用多少核。这也就是说同时运行的其他进程,或者线程关联性(强制线程在某些核或CPU上运行)会影响性能

8.5.单元处理开销

8.5.1.花在流中每个元素身上的时间越长,并行操作带来的性能提升越明显

8.5.2.处理每个元素所花的时间

8.6.通用数据结构性能

8.6.1.性能好

8.6.1.1.ArrayList

8.6.1.2.数组

8.6.1.3.IntStream.range

8.6.1.4.支持随机读取,也就是说它们能轻而易举地被任意分解

8.6.2.性能一般

8.6.2.1.HashSet

8.6.2.2.TreeSet

8.6.2.3.不易公平地被分解,但是大多数时候分解是可能的

8.6.3.性能差

8.6.3.1.LinkedList

8.6.3.2.Streams.iterate

8.6.3.3.BufferedReader.lines

8.6.3.4.难于分解

8.7.无状态操作

8.7.1.整个过程中不必维护状态

8.7.2.map

8.7.3.filter

8.7.4.flatMap

8.8.有状态操作

8.8.1.有维护状态所需的开销和限制

8.8.2.sorted

8.8.3.distinct

8.8.4.limit

9.工具类Arrays

读Java8函数式编程笔记05_数据并行化

发表回复