我刚刚开始学习Scala,所以请耐心等待: - )
我对reduceLeft的行为有疑问。这是一个例子:
List(1, 2, 3, 4, 5) reduceLeft (_ + _)
我想知道计算是否可以同时进行,例如:
第一轮:
第二轮:
如果我只使用reduce函数而不是reduceLeft,那至少就是我期望发生的事情。或者reduceLeft一次只能减少一次吗?
((((1 + 2) + 3) + 4) + 5)
这基本上意味着它不能并行执行,如果可能的话,应该总是倾向于减少reduceLeft / Right?
答案 0 :(得分:9)
答案是肯定的,而且非常简单:
List(1, 2, 3, 4, 5).par.reduce (_ + _)
par
方法将列表转换为并行集合。当您在此并行集合上调用reduce
时,它将并行执行。
答案 1 :(得分:6)
正如您所注意到的,reduceLeft
不可并行化,因为它明确假定一种非关联形式:(B,A) => B
。
只要使用关联运算符,reduce
就可以并行化。
还有一个名为foldLeft
的类似aggregate
,它有两个函数:一个映射为可组合的形式,另一个是关联的元素:(B,A)=>B, (B,B) => B
。
这一个,只要两个函数在输出上达成一致,并且你可以在任何你想要的地方混合零,就可以并行化。
因此,如果您希望能够并行,
reduceLeft/Right -> reduce
foldLeft/Right -> aggregate
在某些情况下reduce
比reduceLeft
更具限制性但aggregate
可以解决问题。
也就是说,这只会使声明能并行。要使实际并行,您需要使用一个继承自ParIterable
的集合,这些集合的名称中都有Par
:ParVector
等。获得并行集合的最简单方法是在常规集合上调用.par
(.seq
从另一个方向调用,从并行到非并行)。它是这样做的,因为除了速度之外,通常没有理由保持并行,但并行性增加了开销。因此,如果有足够的工作要做,你应该只能并行操作,而你可能知道,编译器可能不会。因此,您要明确选择所需的集合类型。 (并行集合返回并行,顺序返回顺序。)