I was trying to optimize the Radix Sort code, just because. Nothing more, nothing less. Here it is!!! So tell me, how does it look?
Summary:
instead of a div or mod ,i use left shift and right shift to avoid div or idiv compiler instruction.
the dual instruction is for avoiding jumps and the usual stuff.
btw you can do arr pointer with same code just change obj_arr*&arr
with obj_arr**&arr
and add some function to the class obj_arr
to get unsigned int
example: arr[i]->get_unsigned_int()
.
or operator if that you like.
postdata: take in mind you are using arr of obj class.
#pragma once
#define modpow2(num,div_pow2,mod_pow2) (num>>div_pow2) - (num >> mod_pow2+div_pow2 << mod_pow2)
template<class obj_arr>
unsigned int getmax(obj_arr*& arr, size_t& size);
template<class obj_arr>
void countrad(obj_arr*& arr, obj_arr*& aux_arr, size_t& size, unsigned int*& count, const unsigned int& mod_pow2, const unsigned int& div_pow2);
template<class obj_arr>
void radix_sort_ftl(obj_arr* arr, size_t size, unsigned int mod_pow2 = 4);
template<class obj_arr>
unsigned int getmax(obj_arr*& arr, size_t& size) {
size_t i = modpow2(size,0,1);
unsigned int aux=arr[0];
for (; i < size; i += 2) {
aux = arr[i] * (aux < arr[i]) + aux * (aux >= arr[i]);
aux = arr[i + 1] * (aux < arr[i + 1]) + aux * (aux >= arr[i + 1]);
}
return aux;
}
template<class obj_arr>
void radix_sort_ftl(obj_arr* arr, size_t size, unsigned int mod_pow2) {
unsigned int max = getmax(arr, size) + 1;
obj_arr* aux_arr = new obj_arr[size];
unsigned int* count = new unsigned int[1<< mod_pow2 + 1];
for (unsigned int divpow2 = 0; max > (1<< divpow2); divpow2 += mod_pow2){
countrad(arr,aux_arr,size,count,mod_pow2, divpow2);
}
delete[] aux_arr;
delete[] count;
}
template<class obj_arr>
void countrad(obj_arr*& arr, obj_arr*& aux_arr, size_t& size, unsigned int*& count, const unsigned int& mod_pow2, const unsigned int& div_pow2) {
unsigned int i, move,max_mod=1<<mod_pow2;
i = modpow2(max_mod + 1,0,1);
count[0] = 0;
for (; i < max_mod + 1; i += 2) {
count[i] = 0;
count[i + 1] = 0;
}
i = modpow2(size, 0, 1);
count[modpow2(arr[0],div_pow2,mod_pow2)+ 1] += i;
for (; i < size; i += 2) {
count[modpow2(arr[i], div_pow2, mod_pow2) + 1]++;
count[modpow2(arr[i+1], div_pow2, mod_pow2) + 1]++;
}
i = modpow2(max_mod + 2, 0, 1) + 1;
for (; i < max_mod + 1; i += 2) {
count[i] += count[i - 1];
count[i + 1] += count[i];
}
i = modpow2(size, 0, 1);
move = modpow2(arr[0], div_pow2, mod_pow2);
aux_arr[count[move]] = arr[0];
count[move] += i;
for (; i < size; i += 2) {
move = modpow2(arr[i], div_pow2, mod_pow2);
aux_arr[count[move]] = arr[i];
count[move]++;
move = modpow2(arr[i+1], div_pow2, mod_pow2);
aux_arr[count[move]] = arr[i + 1];
count[move]++;
}
i = modpow2(size, 0, 1);
arr[0] = aux_arr[0];
for (; i < size; i += 2) {
arr[i] = aux_arr[i];
arr[i + 1] = aux_arr[i + 1];
}
}
```