You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何100个协程简单迭代时Dispatchers.Default比Dispatchers.IO更快?

Dispatchers.IO与Dispatchers.Default性能差异疑问

我为探究使用Dispatchers.IO替代Dispatchers.Default的差异,编写了如下代码:

runBlocking {
    val list = mutableListOf<Job>()
    val time1 = System.currentTimeMillis()
    for (i in 1..100){
        val job = lifecycleScope.launch(Dispatchers.IO) {
            val c = "c$i"
            Log.i("CoroutineRunnerLog", "Launched a coroutine $c on Thread : ${Thread.currentThread().name}")
            for (j in 1..10){
                Log.d("CoroutineRunnerLog", "Coroutine $c, j = $j, Thread : ${Thread.currentThread().name}")
            }
        }
        list.add(job)
    }
    list.joinAll()
    val time2 = System.currentTimeMillis()
    Log.e("CoroutineRunnerLog", "difference is = ${time2 - time1}")
}

已知Dispatchers.IO线程池最大可扩展至64个线程,而Dispatchers.Default的最大线程数等于CPU核心数(我的设备为8核)。我原本预期Dispatchers.IO性能更优,但实际测试结果显示:

Output :
Dispatchers.IO = 200 - 300 ms
Dispatchers.Default = 80 - 100 ms

我想了解为何线程数更少的Dispatchers.Default反而比Dispatchers.IO运行更快。


原因解析
  • 任务类型与调度器定位不匹配:你的测试任务属于CPU密集型任务(循环执行日志打印,核心是字符串格式化、日志缓冲区写入等CPU操作)。Dispatchers.Default正是为CPU密集型场景设计的,线程数等于CPU核心数,能让每个核心持续处理任务,避免线程竞争;而Dispatchers.IO是为IO密集型任务(如网络请求、文件读写)设计的,这类任务大部分时间处于等待IO响应的状态,需要更多线程来利用空闲时间,但CPU密集型任务用多线程只会增加负担。

  • 线程上下文切换开销:当线程数量超过CPU核心数时,操作系统需要频繁切换线程上下文——保存当前线程的状态、加载下一个线程的状态,这个过程会消耗额外的CPU资源。你的测试中Dispatchers.IO最多会启动64个线程,远多于8核CPU的处理能力,大量的上下文切换直接拉高了总耗时;而Dispatchers.Default的8个线程刚好匹配核心数,每个线程能持续占用CPU,几乎没有上下文切换的额外开销。

  • 日志操作的本质:虽然日志看起来是IO操作,但Android的Log系统经过了优化,实际执行时更多是CPU层面的处理(字符串拼接、缓冲区同步等),并非典型的阻塞IO任务,因此更适合Dispatchers.Default这类针对CPU密集场景优化的调度器。


内容的提问来源于stack exchange,提问作者Roop Kishore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:42:34