Scala Parallel View中的奇怪行为

时间:2012-01-20 06:06:55

标签: scala collections parallel-processing

根据斯卡拉多克的说法,

  

视图是某些集合的惰性版本。映射或过滤器或++等集合转换器在应用于视图时不会遍历任何元素。相反,他们创建了一个新视图,它只记录需要应用操作的事实。

这意味着在访问元素之前不会应用操作。但是平行怎么样?

看一下这个例子:

def tn = Thread.currentThread.getName
val strList = List("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace")
val pvs = strList.par.view.filter{ s => println("f "+ tn); s == "I"}.map{s => println("m " + tn); s.toLowerCase}

第二个将打印出如下:

enter image description here

当您在foreach上应用pvs时,会输出:  enter image description here

我无法理解为什么 Parallel 风格的表现与普通风格不同:

val strList = List("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace")  // or read from a text file , e.g. article.txt 
strList.view.filter{s => println("f");  s == "I"}.map{s => println("m"); s.toLowerCase}.foreach(s => println("p"))

1 个答案:

答案 0 :(得分:1)

因为如果表达式是并行集合视图,解释器通过强制它来计算表达式,以便它可以打印它(实质上强制视图)。尝试将其作为独立的Scala程序运行,或者执行此操作:

scala> object foo { var bar: AnyRef = null }

scala> foo.bar = strList.par.view.filter{ s => println("f "+ tn); s == "I"}.map{s => println("m " + tn); s.toLowerCase}

编辑:

上面的另一个问题是并行视图上的filter方法 - 与常规视图不同,它是通过强制集合来实现的。这意味着当您在并行filter上调用view时,整个过滤后的集合将被强制进入数组,并且必须调用与过滤器关联的谓词。像groupBy这样的方法在常规视图上执行相同的操作。