在LINQ的withDegreeOfParallelism
的scala并行集合中是否有任何等价物来设置将运行查询的线程数?我想并行运行一个需要运行一定数量线程的操作。
答案 0 :(得分:58)
使用最新的主干,使用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 = scala.collection.parallel.ForkJoinTaskSupport@4a5d484a
scala> pc map { _ + 1 }
res0: scala.collection.parallel.mutable.ParArray[Int] = ParArray(2, 3, 4)
在使用fork连接池实例化ForkJoinTaskSupport
对象时,必须将fork join pool的并行级别设置为所需的值(示例中为2
)。
答案 1 :(得分: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个线程。
然而,这可能比设置worker pool参数的效率稍差,我不确定。