为什么java首次运行慢_第一次Java循环运行缓慢,为什么?[Sun HotSpot 1.5,sparc]

发布于:2021-12-03 08:17:38

在Solaris SPARC机器上对一些Java代码进行基准测试时,我注意到我第一次调用该基准测试函数时,它运行EXTREMELY的速度很慢(相差10倍):


第一| 1 | 25295.979毫秒


第二| 1 | 2256.990毫秒


第三 1 | 2250.575毫秒


为什么是这样?我怀疑是JIT编译器,有什么办法可以验证这一点?


编辑:


根据一些答案,我想澄清一下这段代码是我可以发现表现出这种行为的最简单的测试用例。因此,我的目标不是让它快速运行,而是了解正在发生的事情,以便在实际基准测试中避免它。


解决: Tom Hawtin正确地指出我的“慢”时间实际上是合理的。遵循此观察,我将调试器附加到Java进程。在第一阶段,内部循环如下所示:


0xf9037218: cmp %l0, 100


0xf903721c: bge,pn %icc,0xf90371f4 ! 0xf90371f4


0xf9037220: nop


0xf9037224: ld [%l3 + 92], %l2


0xf9037228: ld [%l2 + 8], %l6


0xf903722c: add %l6, 1, %l5


0xf9037230: st %l5, [%l2 + 8]


0xf9037234: inc %l0


0xf9037238: ld [%l1], %g0


0xf903723c: ba,pt %icc,0xf9037218 ! 0xf9037218


在以下迭代中,循环如下所示:


0xf90377d4: sub %l2, %l0, %l3


0xf90377d8: add %l3, %l0, %l2


0xf90377dc: add %l2, 1, %l4


0xf90377e0: inc %l0


0xf90377e4: cmp %l0, 100


0xf90377e8: bl,pn %icc,0xf90377d8 ! 0xf90377d8


因此,HotSpot从内部循环中删除了内存访问,从而将其加速了一个数量级。


课: 做数学!我本来应该做汤姆的计算的。


基准Java代码:


private int counter;


private int nThreads;


private void measure(String tag) throws Exception {


MyThread threads[] = new MyThread[nThreads];


int i;


counter = 0;


for (i = 0; i < nThreads; i++)


threads[i] = new MyThread();


long start = System.nanoTime();


for (i = 0; i < nThreads; i++)


threads[i].start();


for (i = 0; i < nThreads; i++)


threads[i].join();


if (tag != null)


System.out.format("%-20s | %-2d | %.3f ms
", tag, nThreads,


new Double((System.nanoTime() - start) / 1000000.0));


}


public MyBench() {


try {


this.nThreads = 1;


measure("First");


measure("Second");


measure("Third");


} catch (Exception e) {


System.out.println("Error: " + e);


}


}


private class MyThread extends Thread {


public void run() {


while (counter < 10000000) {


// work


for (int j = 0; j < 100; j++)


counter++;


counter -= 99;


}


}


}

相关推荐

最新更新

猜你喜欢