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

Kotlin中异步filter为何比常规filter性能更慢?

Kotlin集合过滤:同步vs异步的性能差异解析

问题描述

处理包含500万元素的集合时,Kotlin常规filter操作耗时仅21ms;尝试通过async结合不同Dispatcher(Unconfined、Default等)实现异步过滤,即使Unconfined为最快配置,耗时仍达791ms。需要解释该性能差异的原因。

常规filter测试代码

import kotlin.system.measureTimeMillis
import kotlinx.coroutines.coroutineScope

suspend fun main() = coroutineScope {
    var i = 0
    val hugeCollection = buildList {
        repeat(5_000_000) {
            add(i++)
        }
    }
    println("Size of hugeCollection: ${hugeCollection.size}")
    var filteredList: List<Int> = listOf()

    val elapsedTime = measureTimeMillis {
        filteredList = hugeCollection.filter { it % 2 == 0 }
    }

    println("Elapsed time: $elapsedTime ms")
    println("Size of filteredList: ${filteredList.size}")
}

输出

Size of hugeCollection: 5000000
Elapsed time: 21 ms
Size of filteredList: 2500000

异步filter测试代码

import kotlin.system.measureTimeMillis
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope

suspend fun main() = coroutineScope {
    var i = 0
    val hugeCollection = buildList {
        repeat(5_000_000) {
            add(i++)
        }
    }
    println("Size of hugeCollection: ${hugeCollection.size}")
    var filteredList: List<Int> = listOf()

    val elapsedTime = measureTimeMillis {
        filteredList = hugeCollection
            .map { number ->
                async(Dispatchers.Unconfined) { Pair(number, number % 2 == 0) }
            }.map { deferredPair -> deferredPair.await() }
            .filter { pair -> pair.second }
            .map { pair -> pair.first }
    }

    println("Elapsed time: $elapsedTime ms")
    println("Size of filteredList: ${filteredList.size}")
}

输出

Size of hugeCollection: 5000000
Elapsed time: 791 ms
Size of filteredList: 2500000

性能差异原因分析

  • 协程创建与调度的巨大开销:异步实现中给每个元素都创建了一个async协程,500万个协程的创建、状态管理、销毁带来了远超过滤操作本身的额外成本。即使使用Dispatchers.Unconfined减少线程切换开销,协程上下文切换的底层逻辑依然会消耗大量资源。
  • 未真正实现并行执行:代码中map { deferredPair -> deferredPair.await() }是逐个等待协程结果,本质还是串行执行——每个await都会阻塞当前协程直到对应任务完成,相当于把原本的串行过滤变成了串行的“创建协程→等待结果”,完全没利用到异步并行的优势,反而叠加了协程开销。
  • 额外的数据转换成本:异步实现多了两次map操作,还需要创建大量Pair对象用于包装元素和过滤结果,这些额外的对象分配、数据转换进一步拉长了执行时间。
  • 同步filter的高度优化:Kotlin标准库的filter方法是经过极致优化的——它直接遍历集合,在原集合上判断元素并构建结果列表,没有多余的对象包装,执行路径紧凑,充分利用了CPU缓存和局部性原理,效率极高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:22:43