为什么第一个"新"比其他"新"慢?



我正在测试我的Java代码的性能,但我注意到第一个new操作比其他操作慢。为什么?

第一次new时间和其他 4

Foo g; // The first new in the first iteration
for (int i = 0; i < 5; i++) {
t1 = System.nanoTime();
g = new Foo(a[i], b[i]);
t2 = System.nanoTime();
v[i] = t2 - t1;
}

v的元素(以ns为单位的时间):

3669398
230476
230611
234191
181668

第一个之后的其他 5new的时间

Foo g = new Foo(a[0], b[0]); 
for (int i = 1; i < 6; i++) {
t1 = System.nanoTime();
g = new Foo(a[i], b[i]);
t2 = System.nanoTime();
v[i - 1] = t2 - t1;
}

v的元素(以ns为单位的时间):

254028
222352
222488
228581
219776

这可能是由于多个问题造成的。

最简单的一个是,当你执行第一个 new 时,类可能还没有加载,所以类加载器需要先加载类。这取决于实际的代码和环境。

一个更复杂但同样可行的原因是Java的优化方式。Java 在编译后不会完成优化。在运行时,Java一直在继续优化。

例如,通过 if 语句的前几次可能会更慢,但如果运行时优化器意识到您每次都以相同的方式进行分支,它可能会对其进行优化,并且突然在该运行时的剩余生命周期中开始运行得更快。

这对你有多大影响取决于Foo做什么。但是,如果这解释了您报告的巨大差异,我会感到惊讶,差异大约高出 15 倍。我不确定实际的差异是什么,因为我没有测量过它们,所以也许我低估了这种可能性。

此外,执行几次操作不是一个很好的基准。如果你的测试用例真的像你的示例一样简单,那么可能还有其他问题,而且它们的范围可能很广。也许运行时仍然承受着刚刚启动的沉重负载,因此线程不断产生,包括在第一次迭代期间。我可以疯狂地猜测,但这就是为什么如果我们真的需要知道为什么一件事与另一件事不同,我们会做很多测试。

最新更新