1

Background: My team works on a Java program which accepts a text as input, processes it and displays the result. Each run of the program is stateless and independent of other runs. We noticed that when running the processing method in a loop on the same text, then consistently, the first run takes the longest time to complete, and the next runs take less and less time, until the execution time stabilizes after a few dozen runs on a value much lower than the initial running time.

I tried to test if this is a general phenomenon for any program, and tried running the following code, which has a nested loop, and measured how long the inner loop took:

String s = "abcefghijklmnopqrstuvwxyz";
int TIMES = 10;
int INNER_TIMES = 1000000; 
long count = 0;     
for (int i = 0; i < TIMES; i++) {       
    long start = System.currentTimeMillis();
    for (int j = 0; j < INNER_TIMES; j++) {
        List<String> list = new ArrayList<>();
        list.add(s);
    }
    count++;
    long end = System.currentTimeMillis();          
    double time = (end - start) / 1000.0;
    System.out.println(count + ": " + time + " seconds");
}

The results were similar to what we had noticed in our program:

1: 0.036 seconds
2: 0.018 seconds
3: 0.016 seconds
4: 0.009 seconds
5: 0.01 seconds
6: 0.009 seconds
7: 0.02 seconds
8: 0.014 seconds
9: 0.009 seconds
10: 0.01 seconds

I tried running this many times, and the results were pretty much consistent. The first run of the inner loop always takes around 0.035-0.036 seconds, and from the 4th run and onwards (even when increasing TIMES to 1000) it takes around 0.008-0.01 seconds (with some exceptions).

Both my team leader and I were stumped about why this happens. Is this a known phenomenon in Java? In software in general? Why does it seem like the software needs to "warm up" before it reaches optimal performance?

Ephi Sachs
  • 13
  • 2
  • Someone else can probably give a detailed explanation, but I have heard that repeated code can get cached in some way, so it runs faster after a few runs. – forgivenson Apr 22 '14 at 17:33
  • 1
    I second that, when the JIT runs code many times, it becomes compiled and therefore runs faster. I presume this is what you are experiencing here! – J_mie6 Apr 22 '14 at 17:34

2 Answers2

3

That's normal behavior for Java applications, which also means that you should not optimize your applications unless it is proven to have a bottleneck identified by usage of a profiler. The JVM will improve the performance of the code by using JIT (Just-In-Time) compilation for your code at runtime.

You can find more info about JIT optimizations here: The Java HotSpot Performance Engine Architecture. Chapter 3. The Java HotSpot Compilers


Besides this, you're doing a pretty naive benchmark of your own code. I suggest you to read How do I write a correct micro-benchmark in Java? to enhance the current results of the evaluation of your code. I also recommend to use JMH, a micro benchmark framework specific for Java platform.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
1

There could be multiple factors at play here:

  • The first time the code is executed, the JIT compiler might be compiling the Java bytecode to native code, such as subsequent calls can be faster (most likely explain the behavior you see)
  • The native code might be cached by the CPU

I believe you can turn off JIT (-Djava.compiler=NONE) to verify the first theory (though I have never turn off JIT before)

Adrian Pang
  • 1,125
  • 6
  • 12
  • The system property to turn off JIT is correct, see also [this article](http://artiomg.blogspot.com/2011/10/just-in-time-compiler-jit-in-hotspot.html). – Giovanni Botta Apr 22 '14 at 17:44