C++ 插入后的排序向量与插入到集合中的排序向量

C++ 插入后的排序向量与插入到集合中的排序向量,c++,performance,sorting,vector,set,C++,Performance,Sorting,Vector,Set,将整数推入一个向量,然后对整个向量进行排序,比将整数插入一个集合更快或更慢,后者在输入时进行排序。对不起,我是C++新手,我不知道如何使用时钟功能。有人能帮忙吗?任何帮助都将不胜感激。提前谢谢 #include <vector> #include <iostream> #include <set> #include <algorithm> using namespace std; vector<int> possibility1;

将整数推入一个向量,然后对整个向量进行排序,比将整数插入一个集合更快或更慢,后者在输入时进行排序。对不起,我是C++新手,我不知道如何使用时钟功能。有人能帮忙吗?任何帮助都将不胜感激。提前谢谢

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

using namespace std;

vector<int> possibility1;
set<int> possibility2;

int main()
{
    random_device rd;
    mt19937 rng(rd());
    uniform_int_distribution<int> uni(0,1000);

    // possibility 1
    for(int i = 0; i < 1000000; i++) {
        int r = uni(rng);
        possibility1.push_back(r);
    }

    // possibility 2
    for(int j = 0; j < 1000000; j++) {
        int r = uni(rng);
        possibility2.insert(r);
    }
}
#包括
#包括
#包括
#包括
使用名称空间std;
载体可能性1;
设置可能性2;
int main()
{
随机器件rd;
mt19937 rng(rd());
统一国际分配单位(01000);
//可能性1
对于(int i=0;i<1000000;i++){
int r=uni(rng);
可能性1.推回(r);
}
//可能性2
对于(int j=0;j<1000000;j++){
int r=uni(rng);
可能性2.插入(r);
}
}
编辑


在这种情况下,时间上的差异并不重要,但如果我有一个包含大量私有变量的大型类,并且有一个生成向量/对象集(也有一个比较函数),那么哪一个更快?

您可以非常简单地确定函数调用的平均运行时间(如sort)使用C++高分辨率时钟,得到两个代码< >时间点< /COD>的差异,用<代码> >现在< /代码>。这个答案很好地解释了如何使用chrono库的该位:

您可以使用这种度量来确定每种情况下排序所需的时间,但是您还应该记住,
set
在执行时进行排序,而
vector
在调用
sort
时进行排序。如果您的应用程序可以受益于跨多个插入分摊成本——例如,您可以在集合中插入元素并以交错操作访问集合中的元素,而不是一次插入所有元素、排序,然后稍后仅访问排序的集合——
set
可能是正确的选择。一些评论者已经提到,正确的选择取决于您的应用程序,这就是为什么建议是确定您自己的基准,然后衡量它们

是将整数放入向量,然后更快地排序,还是将整数放入集合

两者都具有相同的渐近复杂度O(nlogn)

集合是一个更复杂的数据结构,它肯定会有更高的有效阶系数,因此在实践中会比排序向量慢一些

复杂性差异是否对程序的性能有任何显著影响,取决于数据结构的大小与其他复杂性源相比是否足够显著。这可以用轮廓仪测量


然而,例如,如果您需要在插入之间而不是仅在所有插入之后对数据结构进行排序,那么set将比排序向量O(n2)渐进地更简单O(nlogn)


渐近复杂性仅保证在超过某个输入阈值时,集合将更有效。但由于系数较小,对于低于阈值的输入,向量可能更快。影响阈值的因素很多,例如硬件。要找出特定系统的阈值,您可以使用探查器进行测量。

什么更快取决于您的特定需求。使用实际使用的真实数据编写自己的基准测试,并进行自己的计时。通常,对于复制/移动成本较低的类型(特别是使用
std::vector::reserve()
),向量往往更快,但测量是唯一可以确定的方法。对象是什么并不重要(或一个对象的大小)是。重要的是访问模式。你的应用程序是否处理所有项目,然后只读取项目?是否经常对所有项目进行迭代?是否交替删除和插入?所有这些因素都会影响。你没有告诉我们任何一个。在我的测试中,排序向量往往比集合更快(可能是由于缓存位置)您可以创建一个函数来插入正确的排序位置,而不是一直排序。但是显然它比使用集合更费力。考虑一下:<代码> SET>代码>通常被实现为一个红黑树,除了数据之外,每个节点使用3个指针。在64位系统上,这意味着100万<代码> int <代码>。s可能会使用32 MB作为一个集合,4 MB作为一个向量。这对处理器的缓存大小有什么影响?向量还具有缓存友好的优点。您不必在每次插入时都对向量进行排序。您可以使用
std::upper_bound
插入到正确排序的位置@Galik实际上并不重要从同情的角度讲,不管怎样,每次插入都必须移动N个元素(在最坏的情况下,如果我们假设均匀分布,则平均为N/2)。这与插入到后面,然后向下进行一次冒泡排序的迭代非常相似。