Reputation: 326
For a programming exercise, we were told to implement insertion, selection, and bubble sorts (in java). I wanted to test how fast the sorts executed, so I wrote a loop to randomly populate and sort an array 10 times. The first two sorts take about twice as long as the last 8 iterations.. why?
Here I have put relevant portions of code
// class fields
public static final int POPULATE_MAX = 1000000000;
public static final int POPULATE_MIN = -1000000000;
public static void populateRandom(int[] toPopulate)
{
// populate array with random integers within bounds set by class fields
for (int i = 0; i < toPopulate.length; i++)
{
toPopulate[i] = (int)(Math.random() * (POPULATE_MAX - POPULATE_MIN))
+ POPULATE_MIN;
}
} // end of method populateRandom(int[] toPopulate)
public static void insertionSort(int[] toSort) throws IllegalArgumentException
{
if (toSort == null)
{
throw new IllegalArgumentException();
}
if (toSort.length <= 1) return;
int temp;
// Index i points to the next unsorted element; assigned to temp
for (int i = 1; i < toSort.length; i++)
{
temp = toSort[i];
// This loop searches through the sorted portion of the array and
// determines where to put the aforementioned unsorted element
for (int j = i - 1; j >= 0; j--)
{
if (temp < toSort[j])
{
toSort[j + 1] = toSort[j];
if(j == 0)
toSort[j] = temp;
}
else
{
toSort[j + 1] = temp;
break;
} // end of if (temp < toSort[j])
} // end of for (int j = i - 1; j >= 0; j--)
} // end of for (int i = 1; i < toSort.length; i++)
} // end of method insertionSort(int[] toSort) throws IllegalArgumentException
public static void main(String[] args)
{
long time;
for (int testRun = 0; testRun < 10; testRun++)
{
int[] array = new int[100000];
System.out.print(testRun + "...");
populateRandom(array);
time = System.currentTimeMillis();
insertionSort(array);
time = System.currentTimeMillis() - time;
for (int i = 0; i < array.length - 1; i++)
{
if (array[i] > array[i+1]) System.out.println(i + ". Bad");
}
System.out.println(time + " Done");
}
System.out.println("ABS Done");
}
I am guessing that it has to do with branch prediction, but I am not sure as to why subsequent sorts are very noticeably faster.
Upvotes: 2
Views: 112
Reputation: 30455
Likely your JVM is running in interpreted mode for the first couple iterations, then it notices that you are running the same method repeatedly and compiles it to native code. If you call the same method an even greater number of times, it may even cause further optimizations to "kick in".
Because the JVM works this way, you should always warm your JVM up before taking performance measurements. Basically, run the code you want to benchmark in a loop a bunch of times, then do the measurements. (Note: this should happen within the space of a single JVM process run -- if the JVM exits and starts up again, you're back to square one.)
Upvotes: 4