声明3个int与new int[3]的性能差异及首段执行慢因探究
为什么首次执行的代码段总是比第二个慢?执行顺序如何影响性能测试结果?
我编写了3段代码测试性能开销,最后一段显示主入口可能存在额外开销,但核心问题仍在前两段:
测试情况1:先声明3个int变量
int size = Integer.MAX_VALUE; long ms = System.currentTimeMillis(); for (int i = 0; i < size; i++) { int a = 10; int b = 20; int c = 30; } System.out.println((System.currentTimeMillis() - ms)); ms = System.currentTimeMillis(); for (int i = 0; i < size; i++) { int[] arr = new int[3]; arr[0] = 10; arr[1] = 20; arr[2] = 30; } System.out.println((System.currentTimeMillis() - ms));
输出:
9 2
测试情况2:先执行new int[3]
int size = Integer.MAX_VALUE; long ms = System.currentTimeMillis(); for (int i = 0; i < size; i++) { int[] arr = new int[3]; arr[0] = 10; arr[1] = 20; arr[2] = 30; } System.out.println((System.currentTimeMillis() - ms)); ms = System.currentTimeMillis(); for (int i = 0; i < size; i++) { int a = 10; int b = 20; int c = 30; } System.out.println((System.currentTimeMillis() - ms));
输出:
8 1
测试情况3:添加延迟排除主入口影响
try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } int size = Integer.MAX_VALUE; long ms = System.currentTimeMillis(); for (int i = 0; i < size; i++) { int a = 10; int b = 20; int c = 30; } System.out.println((System.currentTimeMillis() - ms)); ms = System.currentTimeMillis(); for (int i = 0; i < size; i++) { int[] arr = new int[3]; arr[0] = 10; arr[1] = 20; arr[2] = 30; } System.out.println((System.currentTimeMillis() - ms));
输出:
1 2
核心原因分析
按逻辑new int[3]的内存分配应该更耗时,但实际首次执行的代码段总是更慢,本质是JVM即时编译(JIT)的预热机制在起作用:
- 解释执行 vs 编译执行:JVM启动后,代码默认以解释模式运行,逐行翻译字节码执行,速度较慢。当一段代码被多次执行(达到JIT编译阈值),JVM会将其编译为机器码,后续执行直接运行优化后的机器码,速度大幅提升。
- 测试顺序的影响:第一个循环运行时,JVM还在收集代码的执行信息,尚未触发JIT编译;等第一个循环跑完,JVM已经完成了编译准备,第二个循环直接享受编译优化后的执行效率,所以速度更快。
- 无效代码的极致优化:你测试的两段代码都属于"无副作用"的无效代码(变量/数组未被后续使用),JIT会直接将整个循环优化掉——这也是第三种测试里,预热后的变量声明循环只需要1ms、数组循环也只有2ms的原因。
内容的提问来源于stack exchange,提问作者vnoob0
相关产品推荐
相关产品推荐

