我在Akka中有以下“分而治之”框架:
trait DivideAndConquer[Args,Result] {
def shouldDivide(args: Args): Boolean
def sequential(args: Args): Result
def divide(args: Args): Seq[Args]
def merge(results: Seq[Result]): Result
/////////////////////////////////
def concurrent(args: Args)(implicit ec: ExecutionContext): Result = {
if( !shouldDivide(args) )
sequential(args)
else {
val futures = divide(args).map { d => Future { concurrent(d) }}
val merged = Future.sequence(futures).map { merge }
Await.result(merged, Duration( 30, TimeUnit.SECONDS ))
}
}
}
shouldDivide是Args大小的一些功能。如果shouldDivide的阈值很小,则会产生
java.lang.OutOfMemoryError: unable to create new native thread
几乎与输入大小无关。
未来的测序代码是否正确地执行此操作?是否应该使用特定的执行程序(它当前是fork-join)。
编辑:然后为某些特定算法创建子类,例如
case class Quicksort() extends DivideAndConquer[List[Int],List[Int]] {
val Threshold = 20000
override def shouldDivide(data: List[Int]): Boolean =
data.length > Threshold
override def sequential(data: List[Int]): List[Int] = qsort(data)
override def divide(data: List[Int]): Seq[List[Int]] = {
val pivot = data.head
val (l,r) = data.tail partition (_ < pivot)
Seq( l, List(pivot), r )
}
override def merge(data: Seq[List[Int]]): List[Int] = {
require(data.size == 3)
data(0) ++ data(1) ++ data(2)
}
}
和客户端代码如下:
val sorted = Quicksort.concurrent(someData)