在C ++中对范围(没有重复)进行排序,是std :: vector和std :: sort比std :: set更快吗?

时间:2012-02-22 18:37:39

标签: c++ performance sorting

我有一个double序列(没有重复),我需要对它们进行排序。填充vector然后sortinsert set中的#include <vector> #include <set> #include <algorithm> #include <random> #include <iostream> std::uniform_real_distribution<double> unif(0,10000); std::default_random_engine re; int main() { std::vector< double > v; std::set< double > s; std::vector< double > r; size_t sz = 10; for(size_t i = 0; i < sz; i++) { r.push_back( unif(re) ); } for(size_t i = 0; i < sz; i++) { v.push_back(r[i]); } std::sort(v.begin(),v.end()); for(size_t i = 0; i < sz; i++) { s.insert(r[i]); } return 0; } 更快地填充它吗?

这个问题是否在不知道标准库的实现(并且不了解程序将运行的硬件)的情况下是否可以回答,而只是使用C ++标准提供的信息?

{{1}}

5 个答案:

答案 0 :(得分:5)

从C ++标准来看,我们所能说的是它们都具有相同的渐近复杂度(O(n*log(n)))。

对于无法有效移动或交换的大型物体,该设置可能更快,因为物体不需要移动多次。对于小对象,向量可能更快,因为对它进行排序不涉及指针更新和更少间接。

在任何给定情况下哪个更快只能通过测量(或对实现和目标平台的全面了解)来确定。

答案 1 :(得分:2)

由于数据缓存因素,矢量的使用可能会更快,因为操作的数据将在更连贯的内存区域(可能)。

向量还将具有更少的每值内存开销。

如果可以,请在插入数据之前保留矢量大小,以最大限度地减少使用值填充矢量时的工作量。

答案 2 :(得分:0)

就复杂性而言,两者应该相同,即nlog(n)。

答案 3 :(得分:0)

答案并非微不足道。如果您的软件中有2个主要部分:第一个设置,第二个查找查找的使用超过设置 :排序vector可能更快,原因有两个:

  1. lower_bound <algorithm>函数比<set>的常规树实现更快,
  2. std::vector内存分配的堆页面较少,因此在查找元素时会出现较少的页面错误。
  3. 如果使用情况混合,或查找不再是设置,则<set>会更快。更多信息:Scott Meyers: Effective STL, Item 23

答案 4 :(得分:0)

由于您说过在一个范围内排序,您可以使用partial_sort而不是整理整个集合 如果我们不想打扰现有的集合并希望拥有一个带有排序数据且没有重复数据的新集合,那么std::set为我们提供了一个直接的解决方案。

#include <vector>
#include <set>
#include <algorithm>
#include <iostream>

using namespace std;


int main()
{
    int arr[] = { 1, 3, 4, 1, 6, 7, 9, 6 , 3, 4, 9 };
    vector<int> ints ( arr, end(arr));
    const int ulimit = 5;
    auto last = ints.begin();
    advance(last, ulimit);
    set<int> sortedset;
    sortedset.insert(ints.begin() , last);

    for_each(sortedset.begin(), sortedset.end(), [](int x) { cout << x << "\n"; });
}