在《編程珠璣》中看到作者的的quick sort的速度介於C的qsort和C++的sort之間。
經過3次調優之後始終比C++的sort慢。我在作者的基礎上又進行了若干次調優後,
速度和C++的sort基本持平。
所作的改變是將數組版改成指針版,這使速度得到明顯的提升。
顯然指針效率更高!
我只使用遞歸版本,因爲在我的機器上遞歸版本和迭代版本沒有明顯差異,
原因可能有兩個:(1)打開編譯器優化開關後,編譯器將尾部遞歸自動轉成迭代;
(2)1百萬個元素排序至多遞歸40次,開銷不大。
我測試用的系統是:
OS: fedora 11(kernel:2.6.29.4-167.fc11.i686.PAE)
Compiler: g++ (GCC) 4.4.0 20090506 (Red Hat 4.4.0-4)
Memory: 2G
CPU: Intel(R) Core(TM)2 Duo CPU E7500 @ 2.93GHz
程序編譯:
1 使用 STL sort 版本:
g++ -g -O2 -W -Wall -Wextra -o mytest -DUSE_STLSORT main.cpp
2 使用我的 quick sort 版本:
g++ -g -O2 -W -Wall -Wextra -o mytest main.cpp
如果要看結果,編譯時加 -DCOLL_PRINT 選項(打開此選項速度會變慢很多)。
程序執行:
命令 time ./mytest查看程序執行所用時間。
平均時間兩者都在0m0.115s左右!
下面是代碼, 我只將最後的版本貼在這裏,你可以自己改回數組版,看看速度的差異:
//////////////////////////////////////////////////////////////////////////////////////
main.cpp:
// 2010年 10月 11日 星期一 09:29:26 CST
// author: 李小丹(Li Shao Dan) 字 殊恆(shuheng)
// K.I.S.S
// S.P.O.T
// for test sort
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
#define MAX_NUMBER 1000000
#define MAX_VALUE 6000000
#define SORT_THRESHOLD 48
//#define USE_STLSORT
//#define COLL_PRINT
#ifndef USE_STLSORT
static void quick_sort(int *, int *);
static void insert_sort(int *, int *);
#endif
#ifdef COLL_PRINT
static void print_coll(int *, int);
#endif
int main()
{
srand(time(0));
int *coll = new int[MAX_NUMBER];
for(int i = 0; i < MAX_NUMBER; ++i)
coll[i] = rand() % MAX_VALUE;
#ifdef USE_STLSORT
#warning Use STL sort
sort(coll, coll + MAX_NUMBER);
#else
#warning Use my sort
quick_sort(coll, coll + MAX_NUMBER);
//insert_sort(coll, coll + MAX_NUMBER);
#endif
#ifdef COLL_PRINT
print_coll(coll, MAX_NUMBER);
#endif
delete [] coll;
return 0;
}
#ifndef USE_STLSORT
#define SWAP(a, b, t) (t) = (a); (a) = (b); (b) = (t);
static void quick_sort(int *bp, int *ep)
{
int n = ep - bp;
if(n > SORT_THRESHOLD) {
int t;
int *qp = bp + (n >> 1);
SWAP(*bp, *qp, t)
int qv = *bp;
int *p = bp;
for(int *q = ep - 1;; ++p, --q) {
for(; *p < qv && p < ep; ++p) ;
for(; *q > qv && q >= bp; --q) ;
if(p > q)
break;
SWAP(*p, *q, t)
}
quick_sort(bp, p);
quick_sort(p + 1, ep);
} else {
insert_sort(bp, ep);
}
}
static void insert_sort(int *bp, int *ep)
{
int tmp;
for(int *p = bp + 1, *q; p < ep; ++p) {
tmp = *p;
q = p - 1;
for(; tmp < *q && q >= bp; --q)
*(q + 1) = *q;
*(q + 1) = tmp;
}
}
#endif
#ifdef COLL_PRINT
static void print_coll(int *v, int l)
{
for(int i = 0; i < l;) {
cout << v[i] << '/t';
if(!(++i % 10))
cout << endl;
}
}
#endif