问题 是否已经有一些基于std :: vector的set / map实现?


对于小型集合或地图,使用排序向量通常要快得多,而不是基于树 set/map  - 尤其是5-10元素之类的东西。 LLVM有一些类 本着这种精神,但没有真正的适配器可以提供 std::map 像界面备份一样 std::vector

任何(免费)实现这个吗?

编辑:感谢所有其他想法,但我真的对基于矢量的集合/地图感兴趣。我确实有一些具体情况,我倾向于创建大量的通常少于10个元素的集合/映射,我确实希望减少内存压力。想想例如三角形网格中顶点的邻居边缘,您可以轻松地使用每组3-4个元素的100k组。


1577
2018-01-16 09:51


起源

我从来没有遇到过std :: sets或5或10个元素的地图的性能问题......我认为你不会注意到任何事情。你创造了超过一百万个非常小的std :: set吗? - Daniel Daranas
是的,可能,我面临的更重要的问题是每个集合分配了许多节点,我想避免这些节点。 - Anteru


答案:


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

我推荐一个很棒的(开源)库 洛基。 它有一个基于向量的关联容器实现,它是std :: map的一个替代品,被称为 AssocVector

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

图书馆是由 安德烈亚历山大夫斯库 的作者 现代C ++设计

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


4
2018-02-24 15:41



是的,AssocVector正是我一直在寻找的,谢谢! - Anteru
多年来一直保持这种状态? - einpoklum


如果找不到合适的东西,我只需要在insert上包装一个std :: vector来进行sort(),并使用lower_bound()实现find()。它应该是直截了当的,和定制解决方案一样高效。


3
2018-01-16 20:27



是的,这正是我的计划,但我希望有一些代码可以让我免于此;) - Anteru
为什么在添加元素时只执行“插入到排序数组”操作是不够的?即使用 lower_bound() 那么,也是;然后将所有数据移动1个前进? - einpoklum
此外,这不如定制解决方案有效。考虑一种自定义解决方案,该解决方案将大部分数据保存在向量中,但保留最近插入元素的辅助向量(按插入顺序),从最新到最近搜索。现在假设访问模式是“插入x,删除x,插入x,删除x”n次。定制解决方案将花费O(n)时间 - 并且具有良好的常数 - 而您建议的解决方案将花费O(n ^ 2)时间,并且捶打现金IIANM。 - einpoklum


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


2
2018-01-16 10:12



是的,我知道,实施并不困难,但在浪费时间之前,我宁愿使用一些现成的解决方案。 - Anteru


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

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


2
2018-01-16 16:35



老帖子,但我从合法的谷歌搜索到这里,所以我觉得有必要插入。除非OP,如OP提到,他使用了数千个,那么它不是 一定 微优化了。改进的缓存局部性和减少的矢量间接可能存在明显的差异。 - Tim Seguine
问题是,小集或地图可能有很多副本。 - einpoklum
另外,@ Marcin,我相信你对这个明显的效果是错误的,因为OP可能会保存未缓存的访问。 - einpoklum


老帖子,我知道,但对于最近的访客,Boost的flat_set和flat_map看起来就像你需要的那样。看到 https://theboostcpplibraries.com/boost.container 了解更多信息。


1
2017-11-28 13:27





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


0
2018-01-16 16:53