ステートメントの背後にある合理性を理解しようとして いますブロッキングが絶対に必要な場合は、先物をブロックすることができます (推奨されませんが)
背後にあるアイデアForkJoinPool
は、操作をブロックしているプロセスに参加することです。これは、フューチャーとアクターのエグゼキューター コンテキストの主な実装です。結合をブロックするのに効果的です。
私は小さなベンチマークを書きましたが、この非常に単純なシナリオでは、古いスタイルの先物 (scala 2.9) が 2 倍高速であるように見えます。
@inline
def futureResult[T](future: Future[T]) = Await.result(future, Duration.Inf)
@inline
def futureOld[T](body: => T)(implicit ctx:ExecutionContext): () => T = {
val f = future(body)
() => futureResult(f)
}
def main(args: Array[String]) {
@volatile
var res = 0d
CommonUtil.timer("res1") {
(0 until 100000).foreach { i =>
val f1 = futureOld(math.exp(1))
val f2 = futureOld(math.exp(2))
val f3 = futureOld(math.exp(3))
res = res + f1() + f2() + f3()
}
}
println("res1 = "+res)
res = 0
res = 0
CommonUtil.timer("res1") {
(0 until 100000).foreach { i =>
val f1 = future(math.exp(1))
val f2 = future(math.exp(2))
val f3 = future(math.exp(3))
val f4 = for(r1 <- f1; r2 <- f2 ; r3 <- f3) yield r1+r2+r3
res = res + futureResult(f4)
}
}
println("res2 = "+res)
}
start:res1
res1 - 1.683 seconds
res1 = 3019287.4850644027
start:res1
res1 - 3.179 seconds
res2 = 3019287.485058338