如何使用异步过滤处理大数据?附Kotlin协程实现示例
大型姓名列表的异步过滤与URI获取优化
你的现有代码已经实现了基础异步加载,但针对大型列表还有优化空间——目前是等所有姓名和邮箱加载完成后才串行处理过滤与URI获取,效率可以进一步提升。下面是优化后的实现思路和代码:
现有代码的核心问题
- 先同步等待
names和emails全部加载完成才开始后续处理,没有充分利用并行能力 getContactUri如果是IO密集型操作(比如查询系统联系人URI),在map中串行执行会拖慢整体速度- 过滤后的联系人处理是单线程串行,大型列表下耗时明显
优化后的Kotlin协程代码
suspend fun getContactData(): List<ContactData> = coroutineScope { // 并行加载姓名列表和邮箱映射,无需立即await,让两个IO任务同时执行 val namesDeferred = async(Dispatchers.IO) { getNames() } val emailsDeferred = async(Dispatchers.IO) { getEmails() } // 等待两个加载任务完成 val names = namesDeferred.await() val emails = emailsDeferred.await() // 过滤出有对应邮箱的联系人,然后并行处理每个联系人的URI获取 names.filter { contact -> emails[contact.id] != null } .map { contact -> async(Dispatchers.IO) { val contactEmails = emails[contact.id].orEmpty() ContactData( contact = Contact(contact.id, contact.name, contactEmails, contactEmails), uri = getContactUri(contactEmails) ) } } // 等待所有并行处理的子协程完成,收集结果 .awaitAll() }
关键优化点说明
- 并行加载数据源:用
async分别启动姓名和邮箱的加载任务,让两个IO操作同时进行,减少总等待时间 - 并行处理联系人:对过滤后的每个联系人,用
async在IO线程并行执行getContactUri,避免单线程串行处理的瓶颈 - 结构化并发:全程用
coroutineScope包裹,确保所有子协程执行完毕后才返回结果,自动处理协程生命周期,避免泄漏 - 资源合理利用:Dispatchers.IO会自动管理线程池,无需手动控制线程数量,适合处理大量IO密集型子任务
如果getContactUri是轻量操作,并行带来的收益有限,可以考虑保持串行,但大型列表下并行处理的效率提升会很明显。
内容的提问来源于stack exchange,提问作者Slava
相关产品推荐
相关产品推荐

