I implemented a basic sorting algorithm in Java, and compared its performance to those of native methods (Arrays.sort() and Arrays.parallelSort()). The program is as follows.
public static void main(String[] args) {
// Randomly populate array
int[] array = new int[999999];
for (int i = 0; i < 999999; i++)
array[i] = (int)Math.ceil(Math.random() * 100);
long start, end;
start = System.currentTimeMillis();
Arrays.sort(array);
end = System.currentTimeMillis();
System.out.println("======= Arrays.sort: done in " + (end - start) + " ms ========");
start = System.currentTimeMillis();
Arrays.parallelSort(array);
end = System.currentTimeMillis();
System.out.println("======= Arrays.parallelSort: done in " + (end - start) + " ms ========");
start = System.currentTimeMillis();
orderArray(array);
end = System.currentTimeMillis();
System.out.println("======= My way: done in " + (end - start) + " ms ========");
}
private static int[] orderArray(int[] arrayToOrder) {
for (int i = 1; i < arrayToOrder.length; i++) {
int currentElementIndex = i;
while (currentElementIndex > 0 && arrayToOrder[currentElementIndex] < arrayToOrder[currentElementIndex-1]) {
int temp = arrayToOrder[currentElementIndex];
arrayToOrder[currentElementIndex] = arrayToOrder[currentElementIndex-1];
arrayToOrder[currentElementIndex-1] = temp;
currentElementIndex--;
}
}
return arrayToOrder;
}
When I run this program, my custom algorithm consistently outperforms the native queries, by orders of magnitude, on my machine. Here is a representative output I got:
======= Arrays.sort: done in 67 ms ========
======= Arrays.parallelSort: done in 26 ms ========
======= My way: done in 4 ms ========
This is independent of:
- The number of elements in the array (999999 in my example)
- The number of times the sort is performed (I tried inside a for loop and iterated a large number of times)
- The data type (I tried with an array of double instead of int and saw no difference)
- The order in which I call each ordering algorithm (does not affect the overall difference of performance)
Obviously, there's no way my algorithm is actually better than the ones provided with Java. I can only think of two possible explanations:
- There is a flaw in the way I measure the performance
- My algorithm is too simple and is missing some corner cases
I expect the latter is true, seen as I used a fairly standard way of measuring performance with Java (using System.currentTimeMillis()). However, I have extensively tested my algorithm and can find no fallacies as of yet - an int has predefined boundaries (Integer.MIN_VALUE and MAX_VALUE) and cannot be null, I can't think of any possible corner case I've not covered.
My algorithm's time complexity (O(n^2)) and the native methods' (O(n log(n)))), which could obviously cause an impact. Again, however, I believe my complexity is sufficient...
Could I get an outsider's look on this, so I know how I can improve my algorithm?
Many thanks,
Chris.