2010-09-18 35 views
10

Scala(或Java)的QtConcurrent類似物是什麼?即簡化了MapReduce的實現,並行映射和foldl。 謝謝Scala類似物QtConcurrent

+0

另請參閱http://stackoverflow.com/questions/1751953/concurrent-map-foreach-in-scala/1753224#1753224 – oluies 2010-09-22 20:01:53

回答

3

您只需使用scala.actors.Futures和正常的map/flatMap即可。然而,沒有容易並行的fold

如果你去多主機,我會使用Akka's發送和接收未來。

12

您可以使用Scala Parallel Collections。他們目前是Scala每晚發佈的一部分,並將在Scala 2.9中發佈。這個想法是,大多數常規集合中可用的操作都是並行化的,因此並行集合可以以相同的方式使用。

目前,有幾種可用的集合類型 - 並行範圍,並行數組和並行散列嘗試。例如,您可以將並行陣列像這樣的調用並行mapfold操作:

scala> val pa = (0 until 10000).toArray.par 
pa: scala.collection.parallel.mutable.ParArray[Int] = ParArray(0, 1, 2, 3, 4, 5, 6,... 

scala> pa.map(_ + 1) 
res0: scala.collection.parallel.mutable.ParArray[Int] = ParArray(1, 2, 3, 4, 5, 6, 7,... 

scala> pa map { v => if (v % 2 == 0) v else -v } 
res1: scala.collection.parallel.mutable.ParArray[Int] = ParArray(0, -1, 2, -3, 4, -5,... 

scala> pa.fold(0) { _ + _ } 
res2: Int = 49995000 

還有其他並行採集操作可用。請注意,fold必須採用關聯運算符 - 在上例中,加法是關聯的((A + B)+ C == A +(B + C)),即您可以按任意順序添加數字子序列,並且您將始終獲得相同的總和(reduce有類似的合同)。

要注意的另一件事是傳遞給並行集合的閉包是同時調用的。如果它們有副作用,例如修改環境中的局部變量,則這些訪問必須進行同步。舉例來說,你可以做這樣的事情:

scala> var a = 0                                         
a: Int = 0                                          

scala> pa foreach { a += _ }                                      

scala> a                                           
res1: Int = 49995000    

scala> a = 0 
a: Int = 0 

scala> pa foreach { a += _ } 

scala> a 
res7: Int = 49990086 

,每次有不同的結果,因爲foreach並行調用{ a += _ }。在上面的例子中,a應該是同步的,用鎖或原子保護。

但這個想法是使用內置的組合器來完成一項任務,並傾向於功能性編程,避免了上述示例中的局部副作用。

您可能想要在其他答案中提供的鏈接中更多地瞭解其內部機制。

+0

非常不錯的響應與「微調」遠離突變;-) – 2010-12-13 06:48:46