不同JDK版本下Java Stream性能是否始终低于普通for循环?
关于Java Stream与基础for循环性能对比的解答
先说明你的测试本身有不小的偏差,不能直接当成结论
- 没有做JVM预热:JVM的即时编译要等代码跑足够多次才会触发优化,你总共才循环10次,前几次的耗时包含了类加载、解释执行的额外开销,数据参考价值很低
- 测试数据集太小了:你用的列表只有7个元素,Stream初始化的固定开销占比被拉得特别大,根本反映不了真实业务场景(通常处理的元素都是几千到百万级)的性能表现
- 运行模式不统一:Java 8你是先编译再跑class文件,Java 11、16用的是单文件直接运行的
java xx.java模式,两者的启动开销本身就不一样 - 计时精度不足:纳秒级计时的误差很大,你测试里出现的0耗时其实是计时精度不够导致的,不是真的没有耗时。
你的理解部分正确
- 高版本JDK确实对Stream做了大量优化:从你给出的结果也能看出来,首次运行Stream的耗时从Java 8的54ms降到了Java 11的0.46ms、Java 16的0.7ms,稳定运行后的耗时差距也比Java 8小了非常多
- 但哪怕是优化后的高版本,Stream的性能通常还是会略低于手写的最优for循环:毕竟Stream的管道机制本身有函数调用、上下文调度的固定开销,不过只要元素量级足够大,两者的性能差距一般会缩小到10%以内,要是用并行流,性能甚至会超过你自己手写的并发循环
实际开发的建议
日常写代码优先选Stream就行,它的可读性、可维护性带来的收益远高于那百分之几的性能损耗,只有你定位到某段Stream代码是性能瓶颈的时候,再换成基础for循环优化就够了。
内容的提问来源于stack exchange,提问作者Kedar Raybagkar
相关产品推荐
相关产品推荐

