首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

STL里的stable_sort,如何提高效率

2012-04-19 
STL里的stable_sort,怎么提高效率?我的程序里最耗时的就是这个stable_sort,大家有什么办法?第一开始我用so

STL里的stable_sort,怎么提高效率?
我的程序里最耗时的就是这个stable_sort,大家有什么办法?

第一开始我用sort,后改成stable_sort好些;
数据就是vector<double>,我用stable_sort(v.begin(), v.end());
后来又改成vector<double *>, 但得加上一个smaller<>结构

template<class T>
struct smaller
{
  bool operator () (const T *p0, const T *p1) const { return (*p0 < *p1); }
};

然后又这么写:stable_sort(v.begin(), v.end(), smaller<double>());
又提高了许多,但还是不满意,大家有什么好办法?多谢了。

[解决办法]
qsort试试看
[解决办法]
sort比stable_sort慢?
楼主的数据排序前就是基本有序的?

大概数据有多少?

[解决办法]
按道理说,sort综合了多种排序方法,比qsort和stable_sort都快才对。
[解决办法]
诡异。。
sort是先快速排序,栈一定深时转堆排序,基本有序时换插入排序,应该比stable_sort和qsort快啊。。
[解决办法]
用set 试试
[解决办法]
不能把
sort(multi_distances.begin(), multi_distances.end(), smaller4 <double>()); 
double tmp = product(multi_distances, modeling_factors); 
这2句放在for循环后面吗?每次都排序当然会比较慢。而且每次都是在末尾增加一个数据,然后再排序。
如果必须放在for里面,那么考虑每次新增的数据,是否之前数据的排序关系,不影响的话改用插入排序。

[解决办法]

C/C++ code
这是人家写的一个帖子,看对楼主是否有帮助~时间测试这将我们置身何处?我已经对时间作了一些论断,而且我们还能作些更直觉的预测:比如,在set中插入一个元素将比排序一个vector慢,因为set是一个复杂的数据结构,它需要使用动态内存分配;或者,排序一个list应该和使用stable_sort差不多快,它们都是归并排序的变种。然而,直觉不能取代时间测试。测量很困难 (更精确地说,你要测量什么,又如何测量?),但这是有必要的。    Listing 1的程序构造了一个vector<double>,其中的元素乱序排列,然后用我们讨论过的每个方法(除了qsort()(WQ注:原文如此))反复对它进行排序。在将vector传给每个测试用例时,我们故意使用传值:我们不想让任何一个测试用例得到一个已排序的vector!用Microsoft Visual C++ 7 beta编译程序(结果和g++相似),在500M的Pentium 3上进行,结果如下:    Sorting a vector of 700000 doubles.    sorting method    t (sec)    sort              0.971    qsort             1.732    stable_sort       1.402    heap sort         1.282    list sort         1.993    set sort          3.194    这和期望相符:sort()最快;stable_sort()、堆排序和qsort()稍慢;排序一个list和set(它使用动态内存分配,并且是个复杂的数据结构),更加慢。 (实际上,qsort()有一个不寻常的好成绩:在g++和VC的老版本上,qsort()仅比sort()慢。)    但这不足以称为排序基准测试--太不具有说服力了。我在一个特定的系统上,使用一个特定的(乱序)初始化,来测试排序一个vector<double>。只有实践能决定这些结果有多大的普遍性。至少,我们应该在double以外再作些测试。    Listing 2排序一个vector<string>:它打开一个文件并将每一行拷贝进一个独立的string。因为qsort()不能处理具有构造函数的元素,所以这个测试中不再包括qsort()。以Project Gutenberg的免费电子文本《Anna Karenina》[注4]作为输入,结果是:    Sorting a file of 42731 lines.    sorting method  t (sec)    sort            0.431    stable_sort     1.322    heap sort       0.751    list sort       0.25    set sort        0.43    突然之间,事情发生了变化。我们仍然看到sort()比stable_sort()和堆排序快得多,但list和set的结果发生了戏剧性的变化。使用set的速度几乎和sort()一样,而list实际上更快。发生了什么?    变化是double是原生类型,而std::sting是一个复杂的class。拷贝一个string或将它赋值给另一个,意味着要调用一个函数--甚至意味着需要使用动态内存分配或创建一个mutex锁。平衡点被改变了;排序string比排序double时,赋值的次数将有更多的影响。排序一个list时,根本没有调用赋值运算:定义一个特别的list::sort()成员函数的全部理由就是它通过操纵指向list的内部节点的指针来工作的。重连接一些list的node的指针比拷贝一个string快。    我们再度发现一个老的至理名言:如果你正在处理大的记录,你绝不要排序记录本身,排序指向它们的指针。使用list使得这一点成为自动,但你也能很容易地显式做到这一点:不是排序原始的vector<string>,取而代之,创建一个索引vector,其元素类型是vector<string>::const_iterator,然后排序这个索引vector。你必须告诉sort()如何比较索引vector的元素(你必须确保比较的是iterator所指的值而不是iterator本身),不过这只是个小问题。我们只需提供一个合适的比较函数对象:    template <class Iterator>    struct indirect_lt {      bool operator()(Iterator x, Iterator y) const         { return *x < *y; }    };    Listing 3展示了如何使用indirect_lt,并对比了直接排序和间接排序时的速度。速度的提升是显著的。    Sorting a file of 42731 lines.    sorting method   t (sec)    indirect sort    0.29    sort             0.401    建议    标准C++运行库提供了六个排序方法:qsort(),sort(),stable_sort(),partial_sort(),lsit::sort(),和set/multiset。    你不应该在新代码中使用qsort()。它比sort()慢。它的接口丑陋,因为它需要类型转换,并易于用错。写一个比较函数以传给qsort()可能很麻烦,尤其是在泛型代码中。你不能使用qsort()排序有构造函数或虚函数的东西,或排序C语言的数组以外的任何数据结构。虽然qsort()没有正式说不推荐使用,但它唯一真正的用处是对C语言的向后兼容。    在其它五个排序方法中,前三个是泛型算法,后两个则使用了某些容器的特别特性。所有这些方法默认都使用operator<()来比较对象,但允许在必要时指定用户自己的比较函数。每个都提供了一些特别的特征:l         sort()通常最快。 l         stable_sort()保证了等价元素在顺序上的稳定。 l         partial_sort()允许只排序出前N个元素。l         list::sort()操纵指针,而不是拷贝元素。l         set允许在一个已序区间快速的插入和删除如果你不需要其它四个方法的特别特征,首选通常应该是sort()。 


[解决办法]

探讨
多谢楼上的转贴。我们都要学习这两点:
1.用指针来排序;
2.sort通常情况下是最快的。

引用:
不能把
sort(multi_distances.begin(), multi_distances.end(), smaller4  <double>());
double tmp = product(multi_distances, modeling_factors);
这2句放在for循环后面吗?每次都排序当然会比较慢。而且每次都是在末尾增加一个数据,然后再排序。
如果必须放在for里面,那么考虑每次新增的数据,是否之前数据的排序关系,不影响的话改用插入排序。

我的这个程序就是算大量数据的。
这2句必须放在for循环里面。
每次新增的数据,和之前数据没有任何关系:
(*combine_index[index]).CopyDistancesTo(multi_distances);
这句就是每次都必须产生一个新的值。

[解决办法]
STL里的快排是有改进的,基本有序效率也不会太低的。
[解决办法]
对于随机的数据,sort不比stable_sort慢
如果数据已经基本有序,用insertion sort最快

[解决办法]
把double*改回double以后,比较操作可以改成引用:
bool operator () (const T &p0, const T &p1) const { return (p0 < p1); } 或者直接用less<>
vector也不要用它的迭代器,而是取出首地址然后作为普通数组用,这样可以避开vector中不必要的边界检查。
按理说C原生类型(好像有个专用名词叫POD什么的)拷贝应该不会太耗时间才是,楼主再试试吧。
[解决办法]
就算不能在CopyDistancesTo()的时候插入到合适位置,那在你循环CalculateMultiDistances之后,并没有改变multi_distances里面的内容吧?这样,multi_distances里面前n-1个数就还是有序的,你自己写个函数,把最后那个新加入的数,插入到合适位置不就行了

热点排行