开发者学堂课程【Scala 核心编程 - 进阶:并行集合运算的应用案例】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/610/detail/9064
并行集合运算的应用案例
内容介绍
一、打印1~5
二、查看并行集合中元素访问的线程
三、并行集合的基本介绍
一、打印1~5
新建一个文件,命名为 ParDemo1
def main(args:Array[string]): unit = {
(1 to 5).foreach(println(_))
//’_’写或者不写是等价的,这里的’_’代表从一到五取出的指针区域,’_’也可以不写,
不写的话 foreach 也会默认把一到五传给 println ,写上就明确地把遍历的内容传给 println ,这样理解得更深刻了。
println()
//这里输出的结果是无序的,原因是每个数的打印速度不同,说明是将 println 任务分配给不同 cpu ,调用 println 充分利用了 cpu ,体现了并行运算的特点。
(1 to 5).par.foreach(println(_))
}
运行以后结果:
假如以后遇到一个很大的集合,每个数据都要计算,然后得到一个新的集合,这时在前面加上 par 就很简单,它都支持。
比如之前讲的 list 也适用。
val list = list(1,2,3,4,5)
list.par.map( )
//对 list 里的元素进行 map 运算是多核进行,速度会更快,有兴趣的话可以把数换成更大的,用 for 循环弄上一百万个,然后让 map 里面再循环多点,运行后会发现运行速度会更快,比如说有四个和,加上 par 会快四倍。
二、查看并行集合中元素访问的线程
由于代码简单,为了避免两个代码写到一起,直接新建一个小文件,命名为 Pardemo02 ,快速运行一下。
defmain(args:Array[string]):unit= { Valresult1=(0to100).map{case_=>Thread.currentThread.getName}.distinct //distinct
用来去重,使效果看起来更明显。
Valresult2=(0to100).par.map{case_=>Thread.currentThread
getName}.distinct
println(result1)//非并行
println(“-------------------------------------------------------”)//为了方便区别,添加间隔线。
println(result2)//并行
}
这段代码是从零到一百进行遍历,然后输出当前线程的名字是多少个。
运行一下发现:
第一种运行了大约一百次,只用了一个线程也就是主线程,第二种由于有四个和,因此则用了四个线程,如果有八个和,则有八个线程。表明第一种的运行时间是第二种的四倍,也就是第二种比第一种快四倍,因此并行比非并行效率更高,因此写代码时要充分利用 par .
三、并行集合的基本介绍
以后要充分利用并行集合,这样的话能提高效率,从语言程序上一改就好,不用费力地从整体结构去改,整体结构的改正一般是迫不得已才改,尽量在原始程序上改。
这是并行集合的基本介绍:
1.Scala 为了充分使用多核 CPU ,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。
2.主要用到的算法有:
Divide and conguer 分治算法, Scala 通过 splitters (分解器),
combiners (组合器)等抽象层来实现,主要原理是将计算工作分解很
多任务,分发给一些处理器去完成,并将它们处理结果合并返回
Workstealin 算法【学数学】,主要用于任务调度负载均衡 (load-
balancing) ,通俗点完成自己的所有任务之后,发现其他人还有活没干完,主动(或被安排)帮他人一起干,这样达到尽早干完的目的。
然后接下来讲了两个应用案例:
>打印 1~5
(1 to5).foreach(println(()) printlno
(1to 5).par.foreach(println(())
>查看并行集合中元素访问的线程
object ParDemo02 {
def main(args: Array[String]): Unit={
val result1=(0 to 100).map{case_=>Thread.currentThreadgetName.distinct
val result2=(0 to 100).parmap{case_=> Thread.currentThreadgetNamedistinct println(result1)
//非并行
println("--------------------------------------------") println(result2) //并行}
}