处理scala.collections.parallel中异常缺乏ParList的问题
因此scala 2.9最近出现在Debian测试中,带来了新的并行集合 假设我有一些与处理scala.collections.parallel中异常缺乏ParList的问题,list,scala,map,parallel-processing,scala-collections,List,Scala,Map,Parallel Processing,Scala Collections,因此scala 2.9最近出现在Debian测试中,带来了新的并行集合 假设我有一些与 def expensiveFunction(x:Int):Int = {...} def process(s:List[Int]):List[Int} = s.map(expensiveFunction) 现在,在文档真正出现在我的机器上之前,我收集了一些关于并行集合的信息,我希望通过将列表切换到ParList…来实现并行化。。。但令我惊讶的是,竟然没有!(只是ParVector,ParMap,P
def expensiveFunction(x:Int):Int = {...}
def process(s:List[Int]):List[Int} = s.map(expensiveFunction)
现在,在文档真正出现在我的机器上之前,我收集了一些关于并行集合的信息,我希望通过将列表切换到ParList
…来实现并行化。。。但令我惊讶的是,竟然没有!(只是ParVector
,ParMap
,ParSet
。)
作为一种解决方法,这(或一行等效)似乎足够有效:
def process(s:List[Int]):List[Int} = {
val ps=scala.collection.parallel.immutable.ParVector()++s
val pr=ps.map(expensiveFunction)
List()++pr
}
在我的测试代码中产生大约3倍的性能改进,并实现更高的CPU使用率(四核加上超线程i7)。但它似乎有点笨重
我的问题是一种聚合:
- 为什么没有一个
参数列表
- 如果没有
,是否有 我应该采用更好的模式/习惯用法,以便 我不觉得他们失踪了参数列表
- 我只是“落后于时代”使用列表吗
我的scala程序中有很多(就像我读的所有scala书籍一样
在2.7天内买回来)和
实际上我应该更多地利用
?(我指的是C++领域 我通常需要一个很好的理由来使用向量
overstd::list
)std::vector
当您需要模式匹配(即案例x::xs
)和高效的预结束/迭代时,列表非常有用。但是,当您希望通过索引快速访问、或分割成块或加入(即xs:::ys
)时,它们就不是那么好了
因此,如果您认为这种事情(拆分和连接)正是高效并行所需要的,那么(拥有一个并行的列表
)就没有多大意义。使用:
xs.toIndexedSeq.par
一个列表
不能很容易地分割成不同的子列表,这使得它很难并行化。一是具有O(n)访问权限;另外,列表
不能去掉它的尾部,因此需要包含一个长度参数
我想,采用向量将是更好的解决方案
请注意,Scala的Vector
与std::Vector
不同。后者基本上是标准数组的包装器,是内存中的一个连续块,在添加或删除数据时需要不时复制它。Scala的Vector
是一种专门的数据结构,它允许高效复制和拆分,同时保持数据本身不变。首先,让我向您展示如何制作该代码的并行版本:
def expensiveFunction(x:Int):Int = {...}
def process(s:List[Int]):Seq[Int] = s.par.map(expensiveFunction).seq
这将让Scala为您解决问题——顺便说一句,它使用了ParVector。如果确实需要列表
,请调用.toList
,而不是.seq
至于问题:
- 不存在
ParList
,因为List
本质上是一种非并行数据结构,因为对它的任何操作都需要遍历
- 你应该编码到traits而不是class--
Seq
,ParSeq
和GenSeq
,例如。即使是列表
的性能特征也由LinearSeq
保证
- Scala 2.8之前的所有书籍都没有考虑新的集合库。特别是,这些集合实际上没有共享一致且完整的API。现在他们做到了,你会从中受益匪浅
此外,Scala 2.7中没有像
Vector
这样的集合——一个具有(接近)恒定索引访问的不可变集合