【问题标题】:Is there already some std::vector based set/map implementation?是否已经有一些基于 std::vector 的 set/map 实现?
【发布时间】:2009-01-16 09:51:48
【问题描述】:

对于小型集合或地图,仅使用排序向量而不是基于树的 set/map 通常要快得多——尤其是对于 5-10 个元素的情况。 LLVM 有一些类 in that spirit,但没有真正的适配器可以提供类似 std::map 的接口,支持 std::vector

有任何(免费)实现吗?

编辑:感谢所有替代想法,但我对基于矢量的集合/地图非常感兴趣。我确实有一些特定情况,我倾向于创建大量包含通常少于 10 个元素的集合/映射,并且我确实希望减少内存压力。例如,考虑三角形网格中顶点的相邻边,您很容易得到 100k 组,每组 3-4 个元素。

【问题讨论】:

  • 我从未遇到过 std::sets 或 5 或 10 个元素的映射的性能问题...我认为您不会注意到任何事情。您是否正在创建超过一百万个非常小的 std::set?
  • 是的,可能我面临的更重要的问题是每个集合分配了很多节点,这是我想避免的。

标签: c++ optimization


【解决方案1】:

我只是偶然发现了你的问题,希望还为时不晚。

我推荐一个名为Loki 的优秀(开源)库。 它有一个基于向量的关联容器实现,它是 std::map 的直接替代品,称为 AssocVector

它为访问元素提供了更好的性能(而插入/删除的性能最差)。

该库由Andrei Alexandrescu 的作者Modern C++ Design 编写。

它还包含一些其他非常漂亮的东西。

【讨论】:

  • 这些年一直在维护吗?
【解决方案2】:

如果你找不到合适的东西,我会包装一个 std::vector 在插入时执行 sort(),并使用 lower_bound() 实现 find()。它应该直截了当,并且与自定义解决方案一样高效。

【讨论】:

  • 是的,这正是我的计划,但我希望有一些代码可以帮助我摆脱这种情况;)
  • 为什么在添加元素时只执行“插入排序数组”操作是不够的?即也使用lower_bound();然后将所有数据向前移动 1?
  • 另外,这不会像自定义解决方案那样有效。考虑一个自定义解决方案,它将大部分数据保存在一个向量中,但维护一个最近插入元素的辅助向量(按插入顺序),从最近到最近进行搜索。现在假设访问模式是“插入 x,删除 x,插入 x,删除 x”n 次。自定义解决方案将花费 O(n) 时间 - 并且具有良好的常数 - 而您建议的解决方案将花费 O(n^2) 时间,并且会破坏现金 IIANM。
【解决方案3】:

旧帖子,我知道,但对于最近的访问者,Boost 的 flat_set 和 flat_map 看起来就像你需要的。请参阅https://theboostcpplibraries.com/boost.container 了解更多信息。

【讨论】:

    【解决方案4】:

    我不知道任何这样的实现,但是有一些函数可以帮助处理 STL 中已经存在的排序向量,例如 lower_boundupper_bound

    【讨论】:

    • 是的,我知道,实现起来并不难,但在浪费时间之前,我宁愿使用一些现成的解决方案。
    【解决方案5】:

    如果集合或映射真的很小,通过微优化数据结构获得的性能将几乎没有明显的影响。在搜索小树与小向量时,您可能会节省一两个内存(读取:缓存)查找,这在大局中是微不足道的。

    话虽如此,你可以试试 hash_map。按键查找保证在恒定时间内运行。

    【讨论】:

    • 旧帖子,但我是通过合法的谷歌搜索来到这里的,所以我觉得有必要插话。除非,正如 OP 提到的,他使用了数千个,那么它不是 必要微优化了。改进的缓存局部性和减少的向量间接性可能存在显着差异。
    • 问题是,小集合或地图可能有很多很多副本。
    • 另外,@Marcin,我相信你对明显效果的看法是错误的,因为 OP 可能会保存未缓存的访问。
    【解决方案6】:

    也许您正在寻找无序地图和无序集。尝试查看依赖散列的 TR1 无序容器或 Boost.Unordered 容器库。在界面下方,我不确定他们是否真的使用 std::vector,但我敢打赌它值得一看。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-19
      • 2015-08-09
      • 1970-01-01
      • 2017-05-13
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      相关资源
      最近更新 更多