【问题标题】:std:sort vs inserting into an std::setstd:sort 与插入 std::set
【发布时间】:2013-03-16 07:18:50
【问题描述】:

我正在从 cin 读取一些线段。每条线段由起点和终点表示。二维。 X 和 Y。

输入未排序。它是随机顺序的。 (更新:但我需要它们先按 X 排序,然后按 Y)

我可以读取所有段,将它们存储在向量中,然后调用 std::sort。另一方面,我可以创建一个空的 std::set 并在每个段到达时插入它。该集合将自动保持排序顺序。这两种方法哪一种更有效?

更新:输入的总大小(段数)是预先知道的。

【问题讨论】:

  • @larsmans 感谢您的纠正。从酒吧发帖。 ;)
  • 你为什么不试试呢?真实世界的性能数据 > “网上有人告诉我的”
  • @jalf 我认为这是一个老问题,答案已被普遍接受。另外,在做出决定之前我应该​​尝试多少不同的输入集?
  • 您应该尝试使用与您实际要使用的输入集相匹配的输入集。所以你知道它是如何在你的情况下
  • @AgnelKurian:那是……伤心……

标签: c++ sorting stl set std


【解决方案1】:

您应该确定这两种方法的性能,但可以肯定的是,假设std::vector 上的std::sort 比插入std::set方式,因为局部性效应和隐藏在树插入算法中的大常数。此外,后续的查找和迭代会更快。

(但是,std::set 更适合支持混合的插入和删除/查找/迭代系列。维护向量中的顺序很昂贵,因为每次插入平均需要线性时间。)

【讨论】:

  • 哦,真的吗?那为什么呢?
  • @LightnessRacesinOrbit:与优化良好的排序相比,树插入中的常量非常高(想想红黑树中的重新平衡)。
【解决方案2】:

根据您的需要使用具有适当语义的容器。这种选择通常会自动提高效率。

如果您随后遇到性能瓶颈,请进行一些基准测试。

【讨论】:

  • 我的需求是我应该能够从左到右遍历输入。如果两个输入具有相同的 x,则较小的 y 获胜。
  • @AgnelKurian 如果您的数据没有固有的顺序,请使用集合。它是一团挤进袋子里的东西。作为一个令人愉悦的副作用,您在迭代时会按字典顺序(或您需要的任何内容)对其进行排序,因此,如果您希望在最后这样做,那也很方便。
【解决方案3】:

这确实取决于,但可以肯定std::set 是用于随机插入和删除的。在这种情况下,您只是插入。使用std::vector。 此外,也许更重要的是,如果您事先知道有多少段,您只需分配一次向量,它不会在每次大小翻倍时重新分配内存。

【讨论】:

    【解决方案4】:

    根据经验,提供的保证越严格,您获得的性能就越差。

    插入std::set 保证序列在每次插入后排序

    插入std::vector 并在所有插入完成后调用std::sort 一次 可确保在完成对vector 的所有操作后对序列进行排序。它不需要在所有中间插入期间对向量进行排序。

    std::vector 还表现出更好的空间局部性,并且需要更少的内存分配。 所以我会假设vector 方法更快,但如果性能对你很重要,那么它就足够重要了,可以衡量

    如果您不想使用 your 中的 your 代码来衡量 your 数据集的在您的情况 更快 应用程序,那么您不在乎哪个更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 2018-05-31
      • 1970-01-01
      • 2014-08-10
      • 2018-03-12
      • 2014-08-07
      • 1970-01-01
      相关资源
      最近更新 更多