【问题标题】:Why is a binary search over a sorted vector is slower than std::set find?为什么对排序向量进行二进制搜索比 std::set 查找慢?
【发布时间】:2017-04-09 04:16:20
【问题描述】:

在这里你可以看到代码,运行它,看看时间。

http://rextester.com/MNQZS47293

我在我的机器上得到了类似的结果(使用相同版本的 MSVC),在向量中的查找比在 std::set 中慢。

我希望排序后的向量版本更快,因为数据的局部性更好(缓存更友好)。 在最坏的情况下,我希望它们相似,因为它们都执行二进制搜索,但我不明白为什么 std::set 比排序向量版本快得多。

非常感谢

编辑:对不起,我粘贴了错误的链接(我修改了代码但忘记复制链接)旧代码使用的是 unordered_set,此代码使用的是集合,问题仍然存在:为什么是二进制搜索排序向量比搜索集合慢?我注意到如果元素的数量足够大,那么排序向量会更快,但我仍然无法理解为什么集合可以在任意数量的元素上优于排序向量。

【问题讨论】:

标签: c++ performance c++11 vector set


【解决方案1】:

链接代码似乎使用unordered_set,而不是set

unordered_set 是一个哈希表。那里的搜索是 not 二分搜索。在那里,搜索性能取决于散列函数和负载因子。

【讨论】:

  • 好发现!事实上,对于体面的负载因子,哈希的搜索性能摊销为 O(1)。
【解决方案2】:

对于更新的问题:

-O1-O2 为这两种方法提供了相同的性能。

-Ox 减慢矢量版本。

这是为什么,需要看反汇编或者-Ox级别的细节。它与set.findlower_bound/binary_search 的算法属性无关。

关于数据的局部性。 binary_search 和 set::find 的合理实现具有完全相同的数据位置。该集合甚至可能以从左到右的方式读取数据。

【讨论】:

  • set 的缓存局部性可能会更糟,因为每个节点都包含额外的指针,因此每个缓存行可以存储更少的值。
  • 旧帖子,但很有趣。对于如此小的数据集,该数据集确实可以,因为在这个基准示例中它都在缓存中,并且由于值的小尺寸(8Kb)而不太可能被驱逐。即使有 set 内部的开销,内存也是缓存友好的。当值的数量增加到 100k 时,由于卓越的内存局部性和可预测性,向量会占据很大的领先地位。在现实世界中,缓存不会一直被您的数据填充,因此我希望向量即使在相对较小的数据结构中也能表现得更好。
猜你喜欢
  • 1970-01-01
  • 2021-01-21
  • 2015-09-26
  • 2022-01-24
  • 2013-11-22
  • 1970-01-01
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多