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

Sha*_*nga 5 parallel-processing scala par

我有一个使用List.par的小程序

val x = List(1,2,3,4,5).par.map(y => {
    Thread.sleep(2000)
    println(y)
    y + 1
})

println(x)
Run Code Online (Sandbox Code Playgroud)

输出:

3
1
4
5
2
ParVector(2, 3, 4, 5, 6)
Run Code Online (Sandbox Code Playgroud)

数字并行打印,但是返回值始终保持其顺序。

我的目标是并行执行对SQL数据库的一系列插入语句。

目前,我正在理解。随着语句数量的增加,我想使用ParSeq

但是我担心它是否会导致性能下降。(如果地图实现中保留了额外的代码以保留其顺序,则这会带来性能开销)。

请建议我该怎么做。

slo*_*ouc 6

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

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

您首先观察了自己的println陈述。通过使用非关联二进制运算(例如减法)可以轻松测试第二个:

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

println(a) 
Run Code Online (Sandbox Code Playgroud)

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

整数列表可以由许多工作人员并行映射,因为元素互不依赖。每个工作人员都可以就地执行该操作,而不会影响任何其他元素。因此,即使起初可能不直观,但这种处理确实会从并行化受益(但要使改进显着,您可能需要大量的元素)。

但是,不能同时使用非关联操作来减少相同的列表,因为这些元素确实相互依赖,并且无论您是否这样做,都会有很大的不同:

1-(2-(3-4))

要么

((1-2)-3)-4

这就是为什么对集合的并行处理通常支持reduceand fold,但不支持foldLeftand的原因foldRight

  • 不用担心内部实现,它正在就位。没有重新排序,因为没有洗牌。想象一下,有100人在排队等候。另一种并行的方法是,每个新手给队列中的一个人1美元,然后离开。现在,队列中的每个人都比他们多了1美元,而且这一切都是并行发生的,并且队列中的顺序得以保留。 (3认同)
  • 我不能对插入语句发表评论,因为它是一个更大的话题,而且我没有全部细节(此外,老实说这是一个完全不同的问题)。但是一般来讲,使用`.par`应该可以解决问题。而且,由于与数据库的交谈是有副作用的,因此您的结果极有可能发生乱序,因此不必担心映射列表的情况。 (3认同)