I have made a few sorting benchmarks in various languages, and I'm rather surprised by the performance of the Java program over the C program.
I have programmed the exact same sorting algorithms in both languages, and the Java program finishes almost twice as fast, all other languages are slower than the C implementation except the Java one.
The benchmarks involve running the sorting algorithm on a random array of numbers a set number of times.
I am compiling the program with -O3
and -Ofast
, so I cannot apply any more compiler optimizations.
The exact code can be found here , but here is an excerpt from it:
Java:
public static void benchmark(SortingFunction func, int arraySize, int numTimes, String name, BufferedOutputStream bo) throws IOException {
long start = System.nanoTime();
for (int i = 0; i < numTimes; i ++) {
func.sort(genRandArray(arraySize));
}
long end = System.nanoTime();
double time = (double)(end - start) / 1e9;
System.out.println("It took " + time + " seconds to do " + name + " sort " +
numTimes + " times on arrays of size " + arraySize
);
String out = name+","+numTimes+","+arraySize+","+time;
for (char c : out.toCharArray()) {
bo.write(c);
}
bo.write('\n');
}
public static void insertionSort(int[] array) {
for (int i = 1; i < array.length; i ++) {
int temp = array[i];
int j;
for (j = i - 1; j >= 0 && array[j] > temp; j --) {
array[j+1] = array[j];
}
array[j+1] = temp;
}
}
C:
void benchmark(void (*f)(int *, int), int arr_size, int num_times, char *name,
FILE *fp) {
int *arr;
struct timeval start, end;
double t;
gettimeofday(&start, NULL);
for (int i = 0; i < num_times; i++) {
arr = gen_rand_arr(arr_size);
f(arr, arr_size);
free(arr);
}
gettimeofday(&end, NULL);
t = ((double)(end.tv_sec * 1000000 + end.tv_usec -
(start.tv_sec * 1000000 + start.tv_usec))) /
1000000;
printf("It took %f seconds to do %s sort %d times on arrays of size %d\n", t,
name, num_times, arr_size);
if (fp != NULL) {
fprintf(fp, "%s,%d,%d,%f\n", name, num_times, arr_size, t);
}
}
void insertion_sort(int *arr, int arr_size) {
for (int i = 1; i < arr_size; i++) {
int temp = *(arr + i);
int j;
for (j = i - 1; j >= 0 && *(arr + j) > temp; j--) {
*(arr + j + 1) = *(arr + j);
}
*(arr + j + 1) = temp;
}
return;
}
Are there some optimizations that Java is making to run faster that somehow change the algorithm? What is going on here?
Any explanations would be appreciated.
Here is a table of results that might help explain the difference:
Java:
name | rep | size | time |
---|---|---|---|
Insertion | 10000 | 1200 | 1.033 |
Insertion | 10000 | 5000 | 15.677 |
Insertion | 10000 | 12000 | 88.190 |
Selection | 10000 | 1200 | 3.118 |
Selection | 10000 | 5000 | 48.377 |
Selection | 10000 | 12000 | 268.608 |
Radix | 10000 | 1200 | 0.385 |
Radix | 10000 | 5000 | 1.491 |
Radix | 10000 | 12000 | 3.563 |
Bogo | 1 | 11 | 1.330 |
Bogo | 1 | 12 | 0.572 |
Bogo | 1 | 13 | 122.777 |
C:
name | rep | size | time |
---|---|---|---|
Insertion | 10000 | 1200 | 1.766 |
Insertion | 10000 | 5000 | 26.106 |
Insertion | 10000 | 12000 | 140.582 |
Selection | 10000 | 1200 | 4.011 |
Selection | 10000 | 5000 | 60.442 |
Selection | 10000 | 12000 | 340.608 |
Radix | 10000 | 1200 | 0.430 |
Radix | 10000 | 5000 | 1.788 |
Radix | 10000 | 12000 | 4.295 |
Bogo | 1 | 11 | 1.378 |
Bogo | 1 | 12 | 2.296 |
Bogo | 1 | 13 | 1586.73 |
I cannot say for sure, but this:
for (j = i - 1; j >= 0 && arr[j] > temp; j--) {
arr[j + 1] = arr[j];
}
is not very cache friendly, because you're traversing the list backwards. I would try changing the loop so that the outer loop do the backwards traversing instead of the inner loop.
Apart from that, I can see that you're including the data generation in the benchmark. That's very bad. Generate the data before starting the timer. Like this:
int *arrs[num_times];
for (int i = 0; i < num_times; i++)
arrs[i] = gen_rand_arr(arr_size);
gettimeofday(&start, NULL);
for (int i = 0; i < num_times; i++)
f(arrs[i], arr_size);
gettimeofday(&end, NULL);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.