期末复习,比较了快排(QuickSort)2种不同代码结构实现的性能
C语言下,用生成随机数赋值给3个数组,clock_t来测时间:
#define times 20000 #define length 1000 int w1[times][length]; int w2[times][length]; int w3[times][length]; void fmrand() { srand((unsigned int)time(NULL)); for (int i = 0; i < times; i++) { for (int j = 0; j < length; j++) { w1[i][j]=w2[i][j]=w3[i][j]= rand(); } } }
代码逻辑极度相似的两个快排,前者可以说是全网标准,后者是我根据指导书上的思路改编的:
void SQuickSort(int a[], int left, int right) { int i = left; int j = right; int temp; int pvalue = a[(i + j) >> 1]; while (i < j) { while (a[i] < pvalue) i++; while (a[j] > pvalue) j--; if (i <= j) { temp = a[i]; a[i++] = a[j]; a[j--] = temp; } } if (j > left) SQuickSort(a, left, j); if (i < right) SQuickSort(a, i, right); }
int partition(int a[], int left, int right) { int pvalue = a[(left+right)>>1]; int temp; while (left < right) { while (a[left] < pvalue) left++; while (a[right] > pvalue) right--; if (left <= right) {//指针重合,交换i位置和中枢 temp = a[left]; a[left++] = a[right]; a[right--] = temp; } } if (left - right) return left - 1; else return left; } void QuickSort(int a[], int left, int right) { if (left >= right) return; int p = partition(a, left, right);//找到中枢 QuickSort(a, left, p); QuickSort(a, p+1, right); }
区别只是其中一个包含子函数partition,另一个没有子函数。
Debug x86:
前者速度和我写的归并排序差不多..从堆栈耗费内存方面考虑,那还得选归并。两种快排之间的速度差距也很大,可能是调用子函数时花费更多时间。
Release x86:
这就有点震撼我了,Relasese模式下两种快排以压倒性的差距超越归并,并且两种归并之间的速度差距缩小了,甚至调用子函数的版本更快。
我相信,无论是Debug还是Release模式下,调用子函数都需要花费更多的时间,而在Release模式下,调用子函数的时间大大缩短,可能是由于反复调用一个指针,减少了参数和系统开销。除此之外,Debug和Release的内存管理也有大不同,Release使得需要反复申请或释放内存的指令得到优化。