Java方法中较早执行的语句理应运行速度更慢吗?
Stream收集ArrayList性能测试顺序偏差问题解析
观测到的性能结果与执行顺序强相关的现象,和两种ArrayList初始化逻辑的真实性能差异无关,是不规范微基准测试下JVM与CPU运行机制共同导致的典型测试误差。
测试场景回顾
测试目标为对比Stream元素收集到默认容量ArrayList、预定义容量ArrayList的性能差异,核心测试代码如下:
int capacity = 8000; var master = new ArrayList<Integer>(capacity); for (int i = 0; i < capacity; i++) { master.add(rnd.nextInt()); } print("Adding elements to list with default capacity..."); var sw = Stopwatch.startNew(); List<Integer> defaultList = master .stream() .collect(Collectors.toList()); sw.stop(); String elapsedDefault = sw.toString(); print("Adding elements to list with predefined capacity..."); sw.restart(); List<Integer> predefined = master .stream() .collect(Collectors.toCollection(() -> new ArrayList<>(master.size()))); sw.stop(); String elapsedPredefined = sw.toString(); System.out.println("Time taken with default size: " + elapsedDefault); System.out.println("Time taken with predefined size: " + elapsedPredefined);
当默认容量收集逻辑先执行时,测试输出为:
Adding elements to list with default capacity...
Adding elements to list with predefined capacity...
Time taken with default size: 12.63ms
Time taken with predefined size: 3.66ms
调换执行顺序,让预定义容量收集逻辑先执行时,输出变为:
Adding elements to list with predefined capacity...
Adding elements to list with default capacity...
Time taken with predefined size: 13.17ms
Time taken with default size: 3.23ms
偏差产生的核心原因
- JIT编译预热开销:JVM启动初期采用解释模式执行字节码,只有代码被反复执行触发编译阈值后,JIT即时编译器才会将其优化编译为本地机器码,执行效率会有数倍提升。测试中先执行的逻辑永远处于解释执行或未完成全量优化的状态,后执行的逻辑可以直接复用JIT对Stream调用链、ArrayList操作的编译优化结果,因此无论测试的是哪种初始化逻辑,永远是先执行的用例耗时更高,和是否预分配容量没有关联。
- CPU硬件层面的预热开销:第一次执行相关代码时,对应的指令、操作数据还未加载到CPU多级缓存中,分支预测器也没有积累对应的执行历史,访存延迟、分支预测失败的回滚开销会远高于后续重复执行的场景,这部分额外开销会被全部计入先执行的测试用例耗时中。
- 运行时噪声干扰:第一次执行集合收集时产生的临时对象可能触发新生代GC,JVM后台编译线程、GC线程的调度带来的额外停顿,也会叠加在先执行的测试结果上,对于毫秒级的小数据量测试来说,这类干扰足以完全盖过真实的性能差异。
实际性能规律
测试备注中提到的规律符合真实场景:
- 小数据量(如本次测试使用的8000元素级别)下,ArrayList动态扩容触发的数组拷贝开销本身极小,很容易被上述运行时噪声掩盖,无法测出稳定的性能差异。
- 只有当元素规模达到数亿级别时,预分配容量省去的多次数组拷贝、内存申请开销才会累积出可稳定观测的性能优势。
如果要得到准确的微基准测试结果,需要先做多轮预热、多次重复测试取平均值,过滤掉运行时噪声的影响,不能直接用单次执行的耗时下结论。
内容的提问来源于stack exchange,提问作者Fiery Phoenix
相关产品推荐
相关产品推荐

