forEach与map的性能差异对比及Kotlin onEach性能分析
Kotlin中forEach、map、onEach的性能对比与用法辨析
问题场景
假设拥有一个Products集合,需要遍历并将每个元素的价格翻倍。原实现代码:
products.forEach { it.price = it.price * 2 }
被要求替换为map,理由是性能更优,修改后的代码:
products.map { it.price = it.price * 2 }
疑问点:
map是否真的比forEach更快?原因是什么?- Kotlin新版本中的
onEach迭代器性能是否更优?
解答
1. map并不比forEach更快,反而属于错误用法
首先明确两者的设计定位:
- forEach:核心是遍历执行副作用,仅迭代集合中的每个元素,执行传入的操作,无返回值,不会创建新集合。
- map:核心是元素转换+生成新集合,迭代每个元素后,将lambda的返回值收集为一个新集合返回。
你现在的map用法完全违背了它的设计意图:lambda中仅做了原地修改操作,返回的是Unit(Kotlin中无返回值的默认返回类型),这会导致map生成一个包含大量Unit实例的新集合——这完全是不必要的内存开销,遍历过程中还要额外处理新集合的创建和元素添加,性能自然比forEach差很多。
简言之:用map做原地修改,不仅不优化性能,还会浪费内存,是错误的用法。
2. onEach的性能与forEach接近
onEach的设计目的是在链式调用中插入遍历操作,它会迭代每个元素执行副作用,然后返回原集合,方便继续后续的链式调用(比如products.onEach { it.price *=2 }.filter { it.price > 100 })。
性能层面,onEach和forEach几乎没有差异:两者都是单纯遍历集合执行操作,唯一的区别是onEach会返回原集合,而forEach无返回值。如果只是单纯的原地修改元素,两者的性能表现基本一致,选择哪个取决于是否需要链式调用的场景。
总结
- 原地修改集合元素时,
forEach是最合理的选择,map在此场景下是错误用法,性能更差。 onEach性能与forEach持平,适合需要保留链式调用的场景,单纯修改元素时两者均可。
内容的提问来源于stack exchange,提问作者Matias Barrios
相关产品推荐
相关产品推荐

