为什么第一个 `new` 比其他的慢?

why the first `new` is slower than the others?

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

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

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

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

例如,通过 if 语句的前几次可能会比较慢,但是如果 运行时间优化器意识到您每次都以相同的方式进行分支,它可能会优化并突然开始 运行在那 运行 的余生中更快。

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

此外,将一个动作做几次并不是一个好的基准。如果您的测试用例真的像您的示例一样简单,那么也可能存在其他问题,而且范围可能很广。可能 运行time 刚启动的时候还承受着很重的负载,所以线程一直在让步,包括在第一次迭代期间。我可以 运行 疯狂地猜测,但如果我们真的需要知道为什么一件事 运行 与另一件事不同,这就是我们进行大量测试的部分原因。