我有一个使用List.par的小程序
val x = List(1,2,3,4,5).par.map(y => {
Thread.sleep(2000)
println(y)
y + 1
})
println(x)
输出:
3
1
4
5
2
ParVector(2, 3, 4, 5, 6)
数字并行打印,但是返回值始终保持其顺序。
我的目标是并行执行对SQL数据库的一系列插入语句。
目前,我正在使用 来理解 。 随着语句数量的增加,我想使用 ParSeq 。
但是我担心它是否会导致性能下降。 (如果 map 实现中存在额外的代码以保留其顺序,则这会带来性能开销)。
请建议我该怎么做。
答案 0 :(得分:6)
Documentation(“语义”部分)解释说,只有两种可能的情况可能导致行为混乱:
第一个您使用println
语句进行了观察。第二种方法很容易通过使用非关联的二进制运算(例如减法)进行测试:
val list = (1 to 100).toList
val a = list.par.reduce(_ - _)
println(a)
尝试多次运行以上代码段。
许多元素可以并行映射整数列表,因为元素彼此不依赖。每个工作人员都可以就地执行该操作,而不会影响任何其他元素。因此,即使起初可能不直观,这种处理还是从并行化中获得了好处(但要想引起明显的改进,您可能需要更多的元素)。
但是,相同的列表不能与非关联操作并行地减少,因为这些元素确实相互依赖,并且您是否这样做会产生很大的不同:
1-(2-(3-4))
或
((1-2)-3)-4
这就是为什么对集合的并行处理通常支持reduce
和fold
,但不支持foldLeft
和foldRight
的原因。