为什么Kotlin使用Sequence.distinct后序列迭代耗时反而更短?
现象原因解释
1. 核心收益来自IO操作量的减少
你的猜测完全正确,println是阻塞IO操作,单次调用的开销是纳秒级的哈希校验开销的成千上万倍。而你的生成逻辑本身会产生大量重复字符串:
- 你的
alphabet包含空字符串,迭代拼接过程中会大量生成和已有短字符串完全重复的结果 - 加了
distinct后,重复元素会直接被过滤,根本不会执行后续的println调用,减少的IO开销完全覆盖了去重的CPU开销
2. distinct的开销特性是分场景的
你之前对distinct是有状态中间操作的认知没有错:
- 它内部基于HashSet实现,每次元素校验的时间复杂度是O(1),开销极低
- 内存开销会随着唯一元素数量的增长而线性上升,这也是你生成8位字符串时触发OOM的原因:所有唯一字符串都被缓存到了HashSet里,超过了JVM堆内存上限
3. 验证方案
你可以做对照测试验证结论:将终端输出的逻辑去掉,改为仅统计元素总数,比如:
val count = iterate(7).count() println("总元素数:$count")
这种场景下没有IO开销的影响,你会观测到不加distinct的执行速度远快于加distinct的版本,符合你最初的理论预期。
权衡逻辑总结
有状态中间操作的开销不是绝对的,需要结合上下游操作的开销、元素重复率综合判断:
- 当下游操作开销高、元素重复率高时,
distinct减少下游执行次数带来的收益会远大于自身的校验开销 - 当下游是纯CPU轻量操作、元素重复率极低时,
distinct的额外开销就会显现 - 数据量极大的场景下,
distinct的内存占用风险会成为核心瓶颈,需要优先考虑
内容的提问来源于stack exchange,提问作者Lor
相关产品推荐
相关产品推荐

