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

时间:2017-07-14 21:31:51

标签: java performance instance performance-testing

我正在测试我的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

第一次

之后的其他5 new的时间
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

1 个答案:

答案 0 :(得分:3)

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

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

更复杂但同样可行的原因是由于Java优化的方式。编译后Java没有完成优化。在运行时,Java一直在不断优化。

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

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

另外,做几次动作不是一个好的基准。如果你的测试用例真的和你的例子一样简单,那么也可能存在其他问题,而且它们可能是广泛的。也许运行时刚刚启动时负载很重,因此线程不断产生,包括在第一次迭代期间。我可以疯狂地猜测,但这是我们为什么要做很多测试的一部分,如果我们真的需要知道为什么一件事情与另一件事情不同。