并行Seq对执行语句序列有何好处?

时间:2019-05-24 13:46:46

标签: scala parallel-processing par

我有一个使用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 实现中存在额外的代码以保留其顺序,则这会带来性能开销)。

请建议我该怎么做。

1 个答案:

答案 0 :(得分:6)

Documentation(“语义”部分)解释说,只有两种可能的情况可能导致行为混乱:

  1. 副作用操作可能导致不确定性
  2. 非关联性操作导致不确定性

第一个您使用println语句进行了观察。第二种方法很容易通过使用非关联的二进制运算(例如减法)进行测试:

val list = (1 to 100).toList
val a = list.par.reduce(_ - _)

println(a) 

尝试多次运行以上代码段。

许多元素可以并行映射整数列表,因为元素彼此不依赖。每个工作人员都可以就地执行该操作,而不会影响任何其他元素。因此,即使起初可能不直观,这种处理还是从并行化中获得了好处(但要想引起明显的改进,您可能需要更多的元素)。

但是,相同的列表不能与非关联操作并行地减少,因为这些元素确实相互依赖,并且您是否这样做会产生很大的不同:

  

1-(2-(3-4))

  

((1-2)-3)-4

这就是为什么对集合的并行处理通常支持reducefold,但不支持foldLeftfoldRight的原因。