【发布时间】:2021-06-03 11:51:48
【问题描述】:
我有一组任务。每个这样的任务通常都很小,除了一些很大的。最初我每个任务都有一个Future。然而,这导致我不得不为少数Futures 等待相当长的时间,这些Futures 在空闲时有很多CPU 的任务更大。我想通过检查任务是否超过一定大小来改变这一点,如果是,则将任务再次拆分为多个 Futures 解决子任务。然而,这会导致性能更差,因为第一组期货突然按顺序执行。没有任何任务或子任务是相关的,因此可以相互独立地解决。
以下是此行为的概念证明。在 Scala 2.13.4 中测试。
import scala.concurrent.{Await, Future, blocking}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.sys.process._
object Main {
val workSet : List[Int] = List(
3000,
3000,
3000,
12000,
3000,
3000,
3000,
12000,
3000,
3000,
3000,
3000,
3000,
)
def stupidWait(wait : Int) : Int = {
println(s"waiting for $wait")
val start = System.currentTimeMillis()
while ( (start + wait) > System.currentTimeMillis()) {}
1
}
def smartWait(wait : Int) : Int = {
val work = if(wait > 3000) {
List(3000,3000,3000,3000)
} else {
List(3000)
}
println(s"smart working with ${work}")
val future = Future.sequence {
work.map {
wait => Future { stupidWait(wait) }
}
}
Await.ready(future, Inf)
1
}
def time() : String = {
"date".!!
}
def main(args : Array[String]) : Unit = {
println(s"${time()} dumb start")
val futureI = Future.sequence {
workSet.map {
wait => Future { stupidWait(wait) }
}
}
Await.ready(futureI,Inf)
println(s"${time()} dumb end")
println(s"${time()} smart start")
val futureII = Future.sequence {
workSet.map {
wait => Future { smartWait(wait) }
}
}
Await.ready(futureII,Inf)
println(s"${time()} smart end")
}
}
输出是:
Thu Mar 4 08:09:42 PM CET 2021
dumb start
...
Thu Mar 4 08:09:54 PM CET 2021
dumb end
Thu Mar 4 08:09:54 PM CET 2021
smart start
...
Thu Mar 4 08:10:39 PM CET 2021
smart end
我原本预计智能等待至少会一样快甚至更快,因为较大的等待时间现在被分成 4 个可能并行的等待时间。然而事实并非如此。
为什么 smartWait 没有更快,我必须如何更改代码才能使 smartWait 按预期工作?
【问题讨论】:
标签: multithreading scala future