【问题标题】:Sorting vector after insertion vs inserting into a set插入后排序向量与插入集合
【发布时间】:2018-05-08 22:41:48
【问题描述】:

将整数推入向量,然后对整个向量进行排序比将整数插入集合更快或更慢,集合在输入时进行排序。抱歉,我是 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::vector::reserve()),向量往往更快,但测量是唯一确定的方法。跨度>
  • 对象(或一个对象的大小)是什么并不重要。重要的是访问模式。您的应用程序是否处理所有内容然后只读取项目?它是否经常迭代所有这些?它会交替移除和插入吗?所有这些因素都考虑在内。你没有告诉我们任何一个。
  • 在我的测试中,排序的 vector 往往比 set 快(可能是由于缓存的局部性)。您可以创建一个函数来插入正确排序的位置,而不是一直排序。但它显然比只使用一个集合更繁琐。
  • 考虑这一点:set 通常实现为红黑树,除了数据之外,每个节点使用 3 个指针。在 64 位系统上,这意味着 100 万个ints 可能会使用 32 MB 作为集合和 4 MB 作为向量。这对你的处理器的缓存大小有什么影响?

标签: c++ performance sorting vector set


【解决方案1】:

是将整数放入向量中,然后排序更快,或者将整数放入集合中

两者具有相同的渐近复杂度 O(n log n)。

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

复杂性差异是否对程序的性能有任何显着影响,取决于数据结构的大小与其他复杂性来源相比是否足够显着。这可以使用分析器进行测量。


但是,例如,如果您需要保持数据结构在次插入之间排序,而不是仅在所有插入之后排序,那么 set 将比排序向量更简单 O(n log n) O(n2).

渐近复杂度只保证超过某个输入阈值,set 会更有效率。但是由于系数较小,对于低于阈值的输入,向量可能仍然更快。许多因素会影响阈值,例如硬件。要找出特定系统的阈值,您可以使用分析器进行测量。

【讨论】:

  • Vector 还具有缓存友好的优势。
  • 您不必在每次插入时都对向量进行排序。您可以使用std::upper_bound 插入正确排序的位置。
  • @Galik 渐近地说并不重要。无论如何,您必须在每次插入时移动 N 个(在最坏的情况下,如果我们假设均匀分布,平均为 N / 2)元素。这与插入到后面并向下进行一次冒泡排序迭代几乎相同。
【解决方案2】:

您可以使用 C++ 高分辨率时钟非常简单地确定函数调用(如排序)的平均运行时间,并获取使用 now 检索的两个 time_point 之间的差异。这个答案很好地解释了如何使用 chrono 库的那个位:C++ Cross-Platform High-Resolution Timer

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

【讨论】:

    猜你喜欢
    • 2011-03-18
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    相关资源
    最近更新 更多