Scala并行集合框架初探
1 并行集合框架简介
Scala 并行集合框架( Parallel Collections Framework)是在2.9版添加的重要功能,用于多核环境的并行计算。
主要用到的算法有:
- divide and conquer : 分治算法
Scala通过splitters,combiners等抽象层来实现,主要原理是将计算工作分解很多任务,分发给一些处理器去完成[,并将它们处理结果合并返回]。
主要用于任务调度负载均衡(load-balancing),通俗点完成自己的所有任务之后,发现其他人还有活没干完,主动(或被安排)帮他人一起干,这样达到尽早干完的目的。
并行集合位于scala.collection.parallel,跟普通集合(regular collections)一样,分immutable和mutable。主要实现类是:
scala.collection.parallel.mutable.ParArray
scala.collection.parallel.mutable.ParHashMap
scala.collection.parallel.mutable.ParHashSet
scala.collection.parallel.immutable.ParRange
scala.collection.parallel.immutable.ParHashMap
scala.collection.parallel.immutable.ParHashSet
scala.collection.parallel.immutable.ParVector
基本上命名是对应普通集合名加"Par"前缀。
2 常见用法
2.1 构造并行集合
像普通集合一样,并行集合都有相对应的object工厂对象来构造集合实例。以ParVector为例:
$ scala> import scala.collection.parallel.immutable.ParVector
$ scala> val a = ParVector(1,2)
a: scala.collection.parallel.immutable.ParVector[Int] = ParVector(1, 2)
$ scala> a.size
res0: Int = 2
$ scala> a == ParVector.apply(1,2)
res1: Boolean = true
2.2 普通集合与并行集合的相互转换
Scala为普通集合类增加par实例方法,用于转换为对应的并行集合;同时,每个并行集合类也有seq实例方法,用于转换到对应的普通集合。如:
scala> List(1,2).par
res0: scala.collection.parallel.immutable.ParSeq[Int] = ParVector(1, 2)
scala> List(1,2).par.seq
res1: scala.collection.immutable.Seq[Int] = Vector(1, 2)
2.3 并行集合和普通集合的公用接口
它们都实现了GenIterable, GenSeq接口。如:
scala> import scala.collection.GenSeq
scala> def p[T](xs: GenSeq[T]) = xs foreach print
scala> p((1 to 5).toList)
12345
scala> p((1 to 5).toList.par)
31245
2.4 并行集合的常用操作
Scala平滑聪明的实现并行集合,并与普通集合公用一致的接口。所以大部分操作就行使用普通集合一样,如foreach, map, flatMap, filter 等。见以下示例:
scala> (1 to 5).par.foreach{it => println(Thread.currentThread);print("^"+ it)}
Thread[ForkJoinPool-1-worker-1,5,main]
Thread[ForkJoinPool-1-worker-3,5,main]
^4Thread[ForkJoinPool-1-worker-3,5,main]
^5Thread[ForkJoinPool-1-worker-0,5,main]
^1Thread[ForkJoinPool-1-worker-3,5,main]
^2^3
scala> (1 to 5).par.map( _ + 100)
res5: scala.collection.parallel.immutable.ParSeq[Int] = ParVector(101, 102, 103, 104, 105)
scala> List(1,2,3).par.filter(_ % 2 == 0)
res6: scala.collection.parallel.immutable.ParSeq[Int] = ParVector(2)
这里要注意的是foreach,是在多个线程下执行,不保证迭代元素顺序了。
3 实践
3.1 普通集合和并行集合的性能简单比较
环境: 本人notebook:Fedora 64位;内存4G;4核CPU
JDK: 1.6.0_26,64-Bit Server VM
Scala: 2.9.0.1,启动参数:scala -J-Xms1200M -J-Xmx2000M
代码如下:
object ParBenchmark {
case class Result(item: Int, c: Long, p: Long) {
override def toString = "%-10s\t%-10d\t%-10d".format(item, c, p)
}
def time(proc: => Any) = {
def curr = System.currentTimeMillis
val s = curr; proc; curr - s
}
def even(i: Int) = i % 2 == 0
def b(count: Int) = Some((1 to count).toList).
map(it => (it, it.par)).headOption.
map { it =>
Result(it._1.size, time(it._1 filter even), time(it._2 filter even))
}
def main(args: Array[String]): Unit = {
println("item\tcommon\tpar")
Array(1, 2, 5, 10, 12, 15, 18, 20).map(_ * 1000000).
foreach { it =>
Runtime.getRuntime.gc()
Thread.sleep(2000)
println(b(it).get)
}
}
}
几次执行结果如下:
item regular par
1000000 36 57
2000000 29 24
5000000 70 926
10000000 133 87
12000000 3381 99
15000000 200 124
18000000 1363 162
20000000 1273 219
item regular par
1000000 32 56
2000000 29 21
5000000 71 928
10000000 134 91
12000000 3390 110
15000000 205 127
18000000 1269 168
20000000 1169 196
初步结论
- 计算数据量少,并行集合性能不占优势,甚至还处于劣势
估计是线程切换、分发合并等额外操作消耗的时间。
- 计算数据量大时,如达到千万级别时,并行集合性能优势凸显出来了
当然这些跟本机硬件环境相关,CPU数内核数越多,并行计算当然更有效率。
4 更深入
深入理解并行集合框架实现的细节,学习《A Generic Parallel Collection Framework》论文;
与JDK 7 fork/join 框架的关系及对比;
5 附录
更多使用见测试用例代码:
https://github.com/itang/_learn/blob/master/scala/what_is_new_scala_2.9.0/src/test/scala/me/itang/learn_scala/what_is_new_scala_290/ParallelSpec.scala
参考资料:
http://kotek.net/blog/quick_look_at_upcoming_parallel_collections_in_scala_2.9
http://infoscience.epfl.ch/record/150220/files/pc.pdf
分享到:
相关推荐
Scala中集合的使用 大学生 1. List 列表的使用 2. Set 集合的使用 3.Map 映射的使用 4. 元组的使用
### Scala 集合框架详解 #### 集合概述 在Scala中,集合框架提供了丰富的数据结构,以便开发者能够高效地处理各种数据组织需求。集合主要分为三类:序列`Seq`、集`Set`以及映射`Map`。所有这些集合都扩展自`...
Scala Play框架是一款基于Java和Scala的开源Web应用框架,它以简洁、高效和模块化著称,被广泛用于构建现代的、反应式的Web服务。在Play框架中,sbt(Simple Build Tool)是默认的构建工具,它允许开发者管理项目...
### Scala 集合数据操作详解 #### 一、引言 Scala作为一种融合了面向对象编程和函数式编程特点的编程语言,在数据处理方面展现出了极强的能力。它内置了一系列强大的集合类,使得开发者能够高效地对数据进行操作。...
9. **并发与并行**:Scala提供了并行集合,方便地进行并行计算。习题可能需要利用并行集合进行大规模数据处理。 10. **Scalatest测试**:Scala的测试框架Scalatest是编写单元测试和集成测试的好帮手。习题可能要求...
scala的orm框架,相比其他orm更为简洁 // Declare a model: case class Artist( name : String, genres : Set[Genre] ) case class Genre( name : String ) // Initialize SORM, automatically generating schema:...
1. Scala集合框架:介绍Scala集合库的基本结构,如Seq、Set、Map等,以及它们与Java集合的区别。 2. 高级特性:可能涉及函数式编程的概念,如高阶函数、惰性求值和不可变性,以及这些特性如何在Scala集合中实现。 3....
Binding.scala 是 Scala 上的数据绑定框架,既可以运行在 JVM 上,也可以通过 Scala.js 编译成 JavaScript 运行在 Node.js 或者浏览器中。Binding.scala 也是一套动态页面开发框架,使你可以直接在代码中内嵌 ...
本课件是针对Scala学习者精心准备的资源,旨在帮助你深入理解和掌握Scala的核心概念,并进一步熟悉在Spark框架中的应用。 首先,我们从"Scala进阶之路-part01-基础.pdf"开始,这部分内容主要涵盖了Scala的基础知识...
spark 框架word count scala源文件 spark 框架word count scala源文件spark 框架word count scala源文件spark 框架word count scala源文件spark 框架word count scala源文件
blueeyes 是一个轻量级的 Scala 的 Web 3.0 框架,提供一个纯异步架构,特别适合用于开发高性能、可伸缩性和高可用性的 Web 应用开发。 标签:blueeyes
[Manning Publications] Play 框架开发 (Scala 实现) (英文版) [出版日期] 2013年10月11日[图书页数] 328页 [图书语言] 英语[图书格式] PDF 格式
- Spark:Apache Spark是一个基于Scala构建的大数据处理框架,展示了Scala在大数据领域的应用。 "Scala编程超级详细的实战书籍.pdf"这本书很可能涵盖了以上所有主题,并通过实例深入浅出地讲解了这些概念,对于...
15. **Java 集合与 Scala 集合的转换**: - 导入 `scala.jdk.CollectionConverters`,可以使用 `.asJava` 和 `.asScala` 转换。 16. **函数 values**: - 编写一个函数,根据给定区间和函数,生成对应的输入输出...
Java开发方面,文档将涵盖如何有效利用Java集合框架,包括ArrayList、LinkedList、HashMap等。理解不同集合的内部实现和适用场景对于优化代码性能至关重要。例如,当需要快速查找时,HashMap是首选;而如果关心插入...
xitrum 是一个 Scala 的 Web 框架,基于 Netty 开发。结构如下图所示: ----------------- | Your app | ----------------- | Xitrum | ; Other instances| ------------- || | Action/View | || -----------...
学习spark之前,大家必须先学会Scala这门语言,他是spark的基础,这里总结了一下Scala集合的相关知识点
总的来说,Akka框架凭借其强大的并发处理能力、分布式系统的设计以及对Scala和Java的友好支持,已经成为现代企业级应用开发的重要选择。深入理解和熟练运用Akka,能够帮助开发者构建出更加健壮、高效的软件系统。
2. **标准库**:Scala的标准库提供了大量的类和模块,包括集合操作、I/O、反射、并发处理等,这些是编写Scala程序的基础。 3. **Scala REPL**:Read-Eval-Print Loop,交互式解释器,允许开发者即时测试代码片段,...