| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 823 人关注过本帖
标题:Sorting efficiency study: sort() is faster than qsort().
只看楼主 加入收藏
HJin
Rank: 6Rank: 6
等 级:贵宾
威 望:27
帖 子:401
专家分:0
注 册:2007-6-9
收藏
 问题点数:0 回复次数:5 
Sorting efficiency study: sort() is faster than qsort().

/*---------------------------------------------------------------------------
File name: sort-efficiency.cpp
Author: HJin (email: fish_sea_bird [at] yahoo [dot] com )
Created on: 8/29/2007 17:40:41
Environment: Windows XP Professional SP2 English +
Visual Studio 2005 v8.0.50727.762


Modification history:
===========================================================================


Problem statement:
---------------------------------------------------------------------------

I was asked "Which sorting algorithm is most efficient for random data?".


Analysis:
---------------------------------------------------------------------------

In this article, we consider four approaches of sorting:

1. STL sort + function pointer;
2. STL sort + functor;
3. STL sort;
4. qsort.

A few ouputs are shown in the Sample ouput section. We conclude that:

a. approach 2 is as efficient as approach 3. The former is more flexible,
since you can define what it means by "a>b" yourself.
b. approach 1 takes longest time to finish. Thus you may want to avoid using
function pointers.
c. approach 4 is less efficient than approach 2 and 3. Or we can conclude,
legacy C code is less efficient than standard C++ code.


Sample output:
---------------------------------------------------------------------------

Test #1, size of input is 13388000
Function pointer: 6.549 seconds.
Functor: 4.166 seconds.
Standard C++: 4.166 seconds.
qsort: 6.559 seconds.

Test #2, size of input is 18258761
Function pointer: 9.073 seconds.
Functor: 5.728 seconds.
Standard C++: 5.718 seconds.
qsort: 8.463 seconds.

Test #3, size of input is 12957326
Function pointer: 6.329 seconds.
Functor: 3.995 seconds.
Standard C++: 3.996 seconds.
qsort: 5.939 seconds.

Test #4, size of input is 12806571
Function pointer: 6.229 seconds.
Functor: 3.936 seconds.
Standard C++: 3.965 seconds.
qsort: 5.799 seconds.

Test #5, size of input is 10091271
Function pointer: 4.847 seconds.
Functor: 3.064 seconds.
Standard C++: 3.085 seconds.
qsort: 4.536 seconds.

Test #6, size of input is 13669040
Function pointer: 6.679 seconds.
Functor: 4.196 seconds.
Standard C++: 4.196 seconds.
qsort: 6.209 seconds.

Test #7, size of input is 18539801
Function pointer: 9.233 seconds.
Functor: 5.818 seconds.
Standard C++: 5.829 seconds.
qsort: 8.572 seconds.

Test #8, size of input is 12031356
Function pointer: 5.828 seconds.
Functor: 3.676 seconds.
Standard C++: 3.665 seconds.
qsort: 5.408 seconds.

Test #9, size of input is 16859086
Function pointer: 8.342 seconds.
Functor: 5.287 seconds.
Standard C++: 5.258 seconds.
qsort: 8.262 seconds.

Test #10, size of input is 19100681
Function pointer: 9.503 seconds.
Functor: 5.999 seconds.
Standard C++: 5.999 seconds.
qsort: 8.932 seconds.


Reference:
---------------------------------------------------------------------------
1. Scott Meyers, Effective C++, Effective STL, etc.
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <ctime>
#include "hjns.h"
#include <cstdio>
#include <cstdlib>

using namespace std;

inline int cmp(const void* a, const void *b)
{
return *(int*)(a)-*(int*)(b);
}

inline bool funcPointer(int a, int b)
{
return a>b;
}

struct functor : public binary_function<int, int, bool>
{
bool operator()(int a, int b)
{
return a>b;
}
};


int main()
{
int i;

for(i=1; i<11; ++i)
{
hj::number::random rd;

// size if random between 10000000 and 20000000, inclusive.
int kSize = rd(10000000, 20000000);
int* a = new int[kSize];

// generate a random array consisting of 1..kSize
hj::number::randPerm(a, kSize);

// make all four input data sets the same
vector<int> v1(a, a+kSize);
vector<int> v2(a, a+kSize);
vector<int> v3(a, a+kSize);

cout<<"\nTest #"<<i<<", size of input is "<<kSize<<endl;
// function pointer approach
{
clock_t start(clock());
sort(v1.begin(), v1.end(), funcPointer);
clock_t elapsed = clock() - start;
cout<<"Function pointer: "<< double(elapsed)/CLOCKS_PER_SEC <<" seconds.\n";
}

// functor approach
{
clock_t start(clock());
sort(v2.begin(), v2.end(), functor());
clock_t elapsed = clock() - start;
cout<<"Functor: "<< double(elapsed)/CLOCKS_PER_SEC <<" seconds.\n";
}

// standard C++
{
clock_t start(clock());
sort(v3.begin(), v3.end(), greater<int>());
clock_t elapsed = clock() - start;
cout<<"Standard C++: "<< double(elapsed)/CLOCKS_PER_SEC <<" seconds.\n";
}

// qsort (legacy C library function)
{
clock_t start(clock());
qsort((void*)a, kSize, sizeof(int), cmp);
clock_t elapsed = clock() - start;
cout<<"qsort: "<< double(elapsed)/CLOCKS_PER_SEC <<" seconds.\n";
}

delete [] a;
}

return 0;
}

搜索更多相关主题的帖子: Sorting efficiency sort study faster 
2007-08-30 09:15
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
收藏
得分:0 

哈哈,HJIN,你真的很爱研究这样的问题,很佩服。

我也把我知道的不多的说下。

从测试的结果其实就很能说明了.

qsort 和 sort 采用的都是优化过的快速排序。
但是在qsort那个时代,c++的模板技术还没出来,而sort采用了functor,这样的模板技术大大的加速的排序,而qsort仍然是通过自定义函数,传指针的方式工作。

所以从代码里发现了,如果给sort传一个函数指针,那么运行效率与qsort一样的,如果通过重载传入functor,那么效率就会很大提高。

至于采用模板技术为什么比调用函数快,那就要靠HJIN再研究给予说明了。我就只知道这么点!不知对否哈!

[此贴子已经被作者于2007-8-30 12:39:28编辑过]


Fight  to win  or  die...
2007-08-30 12:10
HJin
Rank: 6Rank: 6
等 级:贵宾
威 望:27
帖 子:401
专家分:0
注 册:2007-6-9
收藏
得分:0 
It is more about "inline your fuctions".

In approach 2 and 3, there are no function calls since the code is written directly inside "sort()";
In approach 1 and 4, you got the function call overhead.


I am working on a system which has no Chinese input. Please don\'t blame me for typing English.
2007-08-30 12:50
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
收藏
得分:0 

但是如果用inline function不是一样可以在调用点展开吗?这样效果不等同吗?


Fight  to win  or  die...
2007-08-30 13:00
xlh5225
Rank: 2
等 级:论坛游民
威 望:2
帖 子:188
专家分:25
注 册:2007-8-14
收藏
得分:0 
inline function 就不一样了嘛~~~
它省去了函数调用的开销,但是带来了函数展开的内存开销~~~
但是我估计不是inline的问题~~因为在SORT中,有好多循环,用inline是得不常失的(理论上哈~~)
不过编译器在内部做了什么手脚,可能也可以使它的性能增加也不一定哦~~~
2007-08-30 15:53
leeco
Rank: 4
等 级:贵宾
威 望:10
帖 子:1029
专家分:177
注 册:2007-5-10
收藏
得分:0 

struct functor : public binary_function<int, int, bool>
{
bool operator()(int a, int b)
{
return a>b;
}
};

比传函数指针快一些,这个到和我想的不一样。

2007-08-30 16:05
快速回复:Sorting efficiency study: sort() is faster than qsort().
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016606 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved