Kotlin的官方文档提出把协程换成线程试试,这里这么多的线程明显会 OutOfMemoryError。前面我们也提到 Coroutine 的对比对象应该是 Runnable,并且我们有了线程池,还对比啥的线程呢,我们直接看看对比线程池,协程的效率如何:
// ThreadPool4.kt
const val times = 100_000
const val delayTime = 5000L
fun main() {
println("coroutine time: ${measureTimeMillis { coroutine() }}")
println("threadPool time:${measureTimeMillis { threadPool() }}")
}
fun threadPool() {
val scheduledThreadPoolExecutor = ScheduledThreadPoolExecutor(1)
repeat(times) {
scheduledThreadPoolExecutor.schedule({ print(".") }, delayTime, TimeUnit.MILLISECONDS)
}
scheduledThreadPoolExecutor.shutdown()
scheduledThreadPoolExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS)
}
private fun coroutine() = runBlocking {
repeat(times) { // 启动大量的协程
launch {
delay(delayTime)
print(".")
}
}
}
执行 10w 个延时 5s 的任务,可以看到上面 coroutine 的效率和 threadPool 相似,在减去 delay 的 5s 后,效率甚至比 threadPool 还低了 1 倍,说好的高效、轻量级呢?这其实是因为协程有一些包装处理会耗费资源,threadPool 则相对更加简单,差出一倍的效率我们还是可以说两者的效率在同一个数量级(而且真正耗时的是任务的处理,而不在任务的调度上)