2

I'm testing the performance of my Java code, but I noticed that the first new operation is slower then the others. Why?

Time of first new and other 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;
}

Elements of v (time in ns):

3669398
230476
230611
234191
181668

Time of other 5 new after the first

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;
}

Elements of v (time in ns):

254028
222352
222488
228581
219776
  • 3
    Its becouse of JVM optimalization. Code gets optimized on the runtime. Check the JIT optimization https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/underst_jit.html – Antoniossss Jul 14 '17 at 21:33
  • 2
    In general, Java performance measurement is subject to various warm-up factors at the start, such as class loading and JIT optimization. For more details, see https://stackoverflow.com/questions/1481853/technique-or-utility-to-minimize-java-warm-up-time . – Chris Nauroth Jul 14 '17 at 21:34
  • 4
    Using nanotime and such a small sample doesn't really make your benchmark reliable. – Mick Mnemonic Jul 14 '17 at 21:34
  • 2
    The JIT optimisations done by Java are why many benchmarks do a couple of "warm-up" runs when measuring the performance of code. They are not taken into consideration for the final results, their purpose is to load classes into memory, perform JIT optimisations, perhaps prepare the CPU cache. – Aurel Bílý Jul 14 '17 at 21:36
  • 1
    Classes are loaded just in time. When doing the first allocation, the class needs to be loaded first. On subsequent allocations the class will already be in memory – Palle Jul 14 '17 at 21:50

1 Answers1

3

This can be due to multiple issues.

The simplest one is that perhaps the class is not loaded yet when you execute your first new, so the class loader needs to load the class first. That depends on the actual code and environment.

A more complicated but just as feasible reason is due to the way that Java optimizes. Java is not done optimizing after compilation. At runtime, Java continues to optimize all the time.

For example, the first few times through an if statement might be slower, but if the runtime optimizer realizes that you keep branching the same way every time it might optimize that and suddenly it starts running faster for the rest of the life of that runtime.

How much this affects you depends on what Foo does. However, I would be surprised if this accounted for the drastic difference you are reporting, which is about 15 times higher. I am not sure what the actual differences would be though, as I have not measured them, so maybe I am underestimating this possibility.

Also, doing an action a few times is not a good benchmark. If your test case is really as simple as your example, there could be other issues too, and they could be wide ranging. Perhaps the runtime is still under a heavy load from having just started up, so the thread keeps yielding, including during the first iteration. I could run wild with speculations, but that is part of why we do a lot of tests if we really need to know why one thing runs different than another.

Loduwijk
  • 1,950
  • 1
  • 16
  • 28