STL排序比

时间测试
这将我们置身何处?我已经对时间作了一些论断,而且我们还能作些更直觉的预测:比如,
在set中插入一个元素将比排序一个vector慢,因为set是一个复杂的数据结构,它需要
使用动态内存分配;或者,排序一个list应该和使用stable_sort差不多快,它们都是归
并排序的变种。然而,直觉不能取代时间测试。测量很困难 (更精确地说,你要测量什么,
又如何测量?),但这是有必要的。

    Listing 1的程序构造了一个vector
 
 
  
  ,其中的元素乱序排列,然后用我们讨
论过的每个方法(除了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以外再作些测试。

    Listing 2排序一个vector
   
   
    
    :它打开一个文件并将每一行拷贝进一个独立的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
    
    
     
     ,取而代之,创建一个索引vector,其元素类型是vector
     
     
      
      ::const_iterator,然后排序这个索引vector。你必须告诉sort()如
何比较索引vector的元素(你必须确保比较的是iterator所指的值而不是iterator本身),
不过这只是个小问题。我们只需提供一个合适的比较函数对象:

    template 
      
      
        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()。 
      
     
     
    
    
   
   
  
  
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值