比较一下C++ STL sort使用仿函数、函数指针、lambda表达式和运算符重载的速度差异,顺便也和C的qsort对比一下。
测试程序:
#include <bits/stdc++.h>
using namespace std;
#define _for(i,a,b) for(int i=(a); i<(b); ++i)
const int N = 2e7;
struct TS { int a, b, c;} t1[N], t2[N], t3[N], t4[N];
struct DS {
int a, b, c;
bool operator <(const DS& t) const {
if (a != t.a) return a < t.a;
if (b != t.b) return b < t.b;
return c <= t.c;
}
} ds[N];
bool cmp (const TS& t1, const TS& t2) {
if (t1.a != t2.a) return t1.a < t2.a;
if (t1.b != t2.b) return t1.b < t2.b;
return t1.c <= t2.c;
}
int cmp4qsort(const void *a, const void *b) {
TS *t1 = (TS*)a, *t2 = (TS*)b;
if (t1->a != t2->a) return t1->a - t2->a;
if (t1->b != t2->b) return t1->b - t2->b;
return t1->c - t2->c;
}
struct cmpFunctor {
bool operator() (const TS& t1, const TS& t2) {
if (t1.a != t2.a) return t1.a < t2.a;
if (t1.b != t2.b) return t1.b < t2.b;
return t1.c <= t2.c;
}
};
void gen() {
_for(i,0,N) {
t1[i].a = t2[i].a = t3[i].a = ds[i].a = t4[i].a = rand();
t1[i].b = t2[i].b = t3[i].b = ds[i].b = t4[i].b = rand();
t1[i].c = t2[i].c = t3[i].c = ds[i].c = t4[i].c = rand();
}
}
int Time[5];
int n = 10;
int main() {
srand(time(0));
freopen("demo.out", "w", stdout);
for (int i = 0; i < n; i++) {
gen();
clock_t s = clock();
sort(t1, t1+N, cmp);
Time[0] += clock() - s;
s = clock();
sort(t4, t4+N, [] (const TS &t1, const TS &t2) {
if (t1.a != t2.a) return t1.a < t2.a;
if (t1.b != t2.b) return t1.b < t2.b;
return t1.c <= t2.c;
});
Time[1] += clock() - s;
s = clock();
sort(t2, t2+N, cmpFunctor());
Time[2] += clock() - s;
s = clock();
qsort(t3, N, sizeof(TS), cmp4qsort);
Time[3] += clock() - s;
s = clock();
sort(ds, ds+N);
Time[4] += clock() - s;
}
printf("Sort by function pointer: %.4f\n", (double) Time[0] / (n * CLOCKS_PER_SEC));
printf("Sort by lambda: %.4f\n", (double) Time[1] / (n * CLOCKS_PER_SEC));
printf("Sort by functor: %.4f\n", (double) Time[2] / (n * CLOCKS_PER_SEC));
printf("Qsort: %.4f\n", (double) Time[3] / (n * CLOCKS_PER_SEC));
printf("Sort by operator overload: %.4f\n", (double) Time[4] / (n * CLOCKS_PER_SEC));
return 0;
}
结果:
Sort by function pointer: 2.1116
Sort by lambda: 1.8123
Sort by functor: 1.7827
Qsort: 3.4511
Sort by operator overload: 1.6771
结论:
- 运算符重载最快
- 其次是仿函数functor,与运算符重载差不多
- 函数指针算是C++里最慢了
- lambda表达式相当于函数指针的匿名版,优化明显,可能是不需要回调的原因吧
测试条件:-O2
,若去掉该优化,C的qsort
是最快的。