2011-03-24 222 views
36

在LINQ的withDegreeOfParallelism中scala並行集合中是否有任何等價物,它設置將運行查詢的線程數?我想要並行運行一個需要有一定數量的線程運行的操作。scala並行集合並行度

回答

55

與最新的軀幹,使用JVM 1.6或更高版本,可使用:

collection.parallel.ForkJoinTasks.defaultForkJoinPool.setParallelism(parlevel: Int) 

這可能是在將來變化的受試者,雖然。計劃在下一個版本中採用更統一的方法來配置所有Scala任務並行API。

但是,請注意,雖然這將確定查詢使用的處理器數量,但這可能不是運行查詢所涉及的實際線程數。由於並行集合支持嵌套並行性,如果檢測到這種情況,實際的線程池實現可能會分配更多線程來運行查詢。

編輯:

從Scala的2.10開始,要設置的平行水平的優選方法是通過tasksupport字段設置爲一個新的TaskSupport對象,如下面的例子:

scala> import scala.collection.parallel._ 
import scala.collection.parallel._ 

scala> val pc = mutable.ParArray(1, 2, 3) 
pc: scala.collection.parallel.mutable.ParArray[Int] = ParArray(1, 2, 3) 

scala> pc.tasksupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(2)) 
pc.tasksupport: scala.collection.parallel.TaskSupport = [email protected] 

scala> pc map { _ + 1 } 
res0: scala.collection.parallel.mutable.ParArray[Int] = ParArray(2, 3, 4) 

在實例使用fork連接池的ForkJoinTaskSupport對象必須將fork連接池的並行級別設置爲所需的值(示例中爲2)。

5

獨立的JVM版本,使用Scala 2.9+(平行引入集合),你也可以使用的grouped(Int)par功能的組合對小塊執行並行作業,如:

scala> val c = 1 to 5 
c: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5) 

scala> c.grouped(2).seq.flatMap(_.par.map(_ * 2)).toList 
res11: List[Int] = List(2, 4, 6, 8, 10) 

grouped(2)創建長度爲2或更小的塊,seq確保塊的集合不平行(在本例中無用),然後在小平行塊上執行_ * 2函數(使用par創建),從而確保至多2個線程並行執行。

然而,這可能會比設置工作池參數效率稍低,我不確定這一點。

+0

我很懷疑這會給你帶來什麼。我需要看到證明它的基準數字。 – 2013-04-05 19:31:52