Why is the sort faster the second time?
Because by that time, the JIT has optimized the bytecode into faster native code.
There are two effects you need to counter when benchmarking this sort of thing:
- Time taken to JIT the code in the first place
- The way that the native code improves over time as it is optimized harder and harder by the JIT.
Typically you can reduce the effect of this to achieve a steady state by running the code for long enough to get it fully optimized before you start timing.
Additionally, you should use System.nanoTime
instead of System.currentTimeMillis
when benchmarking: System.currentTimeMillis
is meant to give you a reasonably accurate "wall clock" time, which may be adjusted by the operating system if it notices that the clock is out of sync, whereas nanoTime
is specifically designed for measuring elapsed time since a particular instant, regardless of changes to the system clock.