在这篇关于Scala http://beust.com/weblog/2011/08/15/scalas-parallel-collections/
中并行集合的博客文章中Daniel Spiewak的评论中提到了这一点:
其他人已经评论过mkString示例,所以我是 要不管它。它确实反映了更大的一点 集合语义一般。基本上,就是这样:在没有的情况下 副作用(在用户代码中),并行集合具有 完全与顺序集合相同的语义。换一种方式: forAll {(xs:Vector [A],f:A => B)=> (xs.par map f)==(xs map f) }
这是否意味着如果没有副作用并不能实现并行性?如果这是真的,可以扩展这一点来解释为什么会这样吗?
答案 0 :(得分:4)
这是否意味着如果没有副作用并行性不是 实现?
不,这不是它的意思。 Daniel Spiewak说的时候
基本上就是这样:在没有副作用的情况下(在用户代码中), 并行集合具有与顺序完全相同的语义 集合。
这意味着如果您的函数没有副作用,那么使用它来映射简单集合或并行集合将产生相同的结果。这就是原因:
换句话说:forAll {(xs:Vector [A],f:A => B)=> (xs.par map f) ==(xs map f)}
如果f
没有副作用。
所以,实际上恰恰相反:如果存在副作用并行性不是一个好主意,因为结果会不一致。
答案 1 :(得分:3)
它将始终并行运行,但当副作用存在时,结果可能会有所不同。
让我们说A = Int
和B = Int
,代码如下:
var tmp = false
def f(i: Int) = if(!tmp) {tmp = true; 0} else i + 1
所以这里我们有一个带副作用的函数f。在运行代码之前,我假设tmp
为false
。
正在运行Vector(1,2,3).map(f)
将始终生成Vector(0,3,4)
但Vector(1,2,3).par.map(f)
可能有不同的结果。它可以是Vector(0,3,4)
,但由于它是并行的,第二个元素可能先映射等。所以这样的事情可能会发生Vector(2,0,4)
。
您可以确定结果是相同的,在这种情况下f
不会产生副作用。