I wrote a program to test and verify the running time of “insertion sort” which should be O(n^2). The output doesn’t look right to me and it doesn’t seem to vary much between different runs. The other odd thing is that the second time through is always the smallest. I expect there to be greater variance every time I run the program but the run times don’t seem to fluctuate as much as I would expect. I’m just wondering if there are some kind of optimizations or something being done by the JVM or compiler. I have similar code in C# and it seems to vary more and the output is as expected. I am not expecting the running times to square every time but I am expecting them to increase more than they are and I certainly expect a much greater variance at the last iteration.
Sample Output (it doesn’t vary enough for me to include multiple outputs):
- 47
- 20 (this one is ALWAYS the lowest… it makes no sense!)
- 44
- 90
- 133
- 175
- 233
- 298
- 379
-
490
public class SortBench { public static void main(String args[]){ Random rand = new Random(System.currentTimeMillis()); for(int k = 100; k <= 1000; k += 100) { //Keep track of time long time = 0; //Create new arrays each time int[] a = new int[k]; int[] b = new int[k]; int[] c = new int[k]; int[] d = new int[k]; int[] e = new int[k]; //Insert random integers into the arrays for (int i = 0; i < a.length; i++) { int range = Integer.MAX_VALUE; a[i] = rand.nextInt(range); b[i] = rand.nextInt(range); c[i] = rand.nextInt(range); d[i] = rand.nextInt(range); e[i] = rand.nextInt(range); } long start = System.nanoTime(); insertionSort(a); long end = System.nanoTime(); time += end-start; start = System.nanoTime(); insertionSort(b); end = System.nanoTime(); time += end-start; start = System.nanoTime(); insertionSort(c); end = System.nanoTime(); time += end-start; start = System.nanoTime(); insertionSort(d); end = System.nanoTime(); time += end-start; start = System.nanoTime(); insertionSort(e); end = System.nanoTime(); time += end-start; System.out.println((time/5)/1000); } } static void insertionSort(int[] a) { int key; int i; for(int j = 1; j < a.length; j++) { key = a[j]; i = j - 1; while(i>=0 && a[i]>key) { a[i + 1] = a[i]; i = i - 1; } a[i + 1] = key; } } }
Warm up the JVM’s JIT optimization of your function, memory allocators, TLB, CPU frequency, and so on before the timed region.
Add some untimed calls right after seeding the RNG, before your existing timing loop.
Results with warming:
Results without warming: