【问题标题】:When is it worth it to change from std::vector to std::unordered_set?什么时候值得从 std::vector 更改为 std::unordered_set?
【发布时间】:2021-10-15 21:53:57
【问题描述】:

我想制作一个包含少量元素的容器,我将只检查一个元素是否是该集合的一部分。 我知道如果集合足够大,向量将不是合适的容器,因为每项研究都是最坏情况的 O(n),并且有更好的选择使用散列函数或二叉树。 但是我想知道如果我的集合中的元素很少(例如只有 5 个)并且我事先知道会发生什么,将容器实现为具有散列函数的结构是否值得? 也许如果集合不够大,必须应用散列函数带来的开销大于必须遍历 5 个元素。

例如在 C++ 中使用 std::unordered_set 而不是 std::vector。 一如既往,谢谢你

【问题讨论】:

  • 如果您的数据集很小,即少于 CPU 缓存,则使用向量很难被击败。 CPU 是为进行线性遍历而构建的。此外,请避免使用 std::unordered_nnn 容器。它们必须实现,它们基本上是std::vector<std::list<T>>,这不是一个很好的数据结构。
  • 如果您有反映实际使用情况的数据,您应该同时实现和配置文件以确定哪个对程序的访问行为最有效。
  • 要找到权衡取舍的关键点,唯一知道的方法就是尝试两种方法并进行衡量。
  • 这是你需要测试和测量的东西,因为它取决于你正在做什么的细节。通常,当数据集的大小很小时,使用什么容器并不重要,因为任何一个容器都能充分发挥作用。
  • 恐怕这不仅取决于大小,还取决于元素的类型。对于复杂类型,每次比较都可能很昂贵,而哈希可以被缓存(+ 表示集合)。另一方面,对于整数数据,在短数组中搜索整数相当快(+ 表示向量)。

标签: c++


【解决方案1】:

有许多因素会影响std::vector 落后于其他方法的点。请参阅 std::vector faster than std::unordered_set?Performance of vector sort/unique/erase vs. copy to unordered_set 了解出现这种情况的一些原因。因此,对这一点的任何计算都必须相当复杂和复杂。找到这一点最方便的方法是性能测试。

请记住,某些因素取决于所使用的硬件。因此,您不仅需要在开发机器上进行性能测试,还需要在“典型”最终用户机器上进行性能测试。不过,您的开发机器可以给您一个直觉检查(就像Quick Bench 这样的在线工具),让您知道您甚至还没有进入球场。 (个别程序员的直觉是出了名的不可靠。有些人认为 100 是一个很大的数字并担心性能;其他人则在数字达到数十亿之前不担心。这些人中的任何一个都会被其他人的观点所震撼。)

鉴于难以确定std::vector 落后的点,我认为这是提醒premature optimization 通常是浪费时间的好地方。出于好奇调查此性能是可以的,但在将其确定为性能瓶颈之前,请不要为此搁置项目更重要方面的工作。选择最适合您的代码的方法。

话虽如此,我个人认为断点很好,超过 10 个项目。所以对于问题的5元素集合,我会倾向于使用向量而不是回头看。

【讨论】:

  • 我突然想到,cmets 在性能问题上经常说“测试一下看看”,但有人怎么知道这样做呢?我没有找到重复的内容,所以我认为在未来的读者提出这些问题之前可能能够找到包含这些信息的问答组合是合适的。
  • 我喜欢,+1。您还可以添加使用可以使用quickbech 之类的工具进行快速肠道检查
猜你喜欢
  • 2015-10-11
  • 1970-01-01
  • 2023-03-26
  • 2017-07-24
  • 2020-02-01
  • 1970-01-01
  • 2022-03-27
  • 2019-04-26
  • 1970-01-01
相关资源
最近更新 更多