C++ 对于以下情况,哪一种是更好的stl映射还是无序_映射

C++ 对于以下情况,哪一种是更好的stl映射还是无序_映射,c++,visual-c++,stl,C++,Visual C++,Stl,我试图比较某些操作的stl映射和stl无序映射。我在网上看了看,这只会让我更加怀疑哪一个整体上更好。因此,我想根据它们执行的操作对两者进行比较 哪一个在游戏中表现得更快 插入、删除、查找 哪一个需要更少的内存和更少的时间来从内存中清除它。欢迎任何解释 提前感谢您的问题的答案在很大程度上取决于您使用的特定STL实现。实际上,您应该查看STL实现的文档——它可能包含大量关于性能的信息 不过,根据cppreference.com的说法,一般来说,它们通常实现为并支持时间复杂度为O(logn)的操作,而

我试图比较某些操作的stl映射和stl无序映射。我在网上看了看,这只会让我更加怀疑哪一个整体上更好。因此,我想根据它们执行的操作对两者进行比较

哪一个在游戏中表现得更快

插入、删除、查找

哪一个需要更少的内存和更少的时间来从内存中清除它。欢迎任何解释


提前感谢

您的问题的答案在很大程度上取决于您使用的特定STL实现。实际上,您应该查看STL实现的文档——它可能包含大量关于性能的信息

不过,根据cppreference.com的说法,一般来说,它们通常实现为并支持时间复杂度为O(logn)的操作,而通常支持固定时间操作。cppreference.com对内存使用的了解很少;然而,建议地图通常比无序地图使用更少的内存


对于使用Visual Studio 2012的Microsoft软件包的STL实现,它似乎在摊销O(log n)时间内支持这些操作,并在摊销常量时间内支持这些操作。但是,文档中没有明确说明内存占用。

两者兼有的原因是两者都不是更好的整体

使用任何一个。如果另一个更适合您的使用,请切换

  • 地图为更糟糕的时间提供了更好的空间
  • 无序的_映射为更差的空间提供了更好的时间
哪一个在插入、删除和查找中执行得更快?哪一个需要更少的内存和更少的时间来从内存中清除它。欢迎任何解释

对于特定的使用,您应该尝试使用实际数据和使用模式,看看哪一种更快。。。有足够多的因素,假设其中任何一方总是“赢”都是危险的

无序映射/哈希表的实现及其特点

学术上,随着元素数量向着无穷大的方向增加,在<代码> STD上的操作::unOrdEdjPMAP < /C> >(这是C++计算程序库提供的计算科学术语“哈希表”或“哈希表”)将趋向于继续占用相同的时间O(1)(忽略内存限制/缓存等),而对于

std::map
(平衡二叉树),每当元素数量加倍时,通常需要执行额外的比较操作,因此它会逐渐变慢O(log2n)

std::unordered_map
实现:基本期望是将有一个连续的“bucket”数组,每个bucket逻辑上是散列到其中的任何值的容器

它通常用于将哈希表描绘成
向量
,其中从向量元素到值涉及至少一个指针解引用,因为您跟随存储在bucket中的列表头指针到初始列表节点;插入/查找/删除操作的性能取决于列表的大小,列表的大小平均等于
无序映射的大小

如果降低了(默认值为1.0),则冲突会减少,但在插入过程中会有更多的重新分配/重新灰化以及更多的内存浪费(这会通过增加缓存未命中而影响性能)

这个最明显的
无序映射
实现的内存使用包括列表头迭代器/指针大小的桶的连续数组和每个键/值对一个双链接列表节点。通常,
bucket\u count()
+2*
size()
额外的开销指针,针对实现可能执行的动态内存分配请求大小的任何舍入进行调整。例如,如果你要100个字节,你可能会得到128、256或512。实现的动态内存例程可能也会使用一些内存来跟踪分配的/可用的区域

仍然,C++标准为现实世界的实现留出空间,以做出一些自己的性能/内存使用决策。例如,在分配新的较大数组后,它们可以将旧的连续存储桶数组保留一段时间,因此可以逐步将值重设为后者,以降低最坏情况下的性能,但代价是平均情况下的性能,因为在操作期间会参考两个数组

映射/平衡二叉树的实现及其特点
map
是一个二叉树,可以使用指针将不同的堆内存区域链接到
new
。除了键/值数据,树中的每个节点都需要父指针、左指针和右指针(查看是否丢失)

比较 因此,
unordered_map
map
都需要为键/值对分配节点,前者通常有两个指针/迭代器开销用于上一个/下一个节点链接,而后者有三个指针/迭代器开销用于父/左/右。但是,
unordered\u映射
还为
bucket\u count()
bucket(=
size()
/
load\u factor()
)提供了单个连续分配

在大多数情况下,内存使用率并没有显著差异,而且一个额外区域的释放时间差异也不太明显

另一种选择 对于那些先填充容器,然后在不进行进一步插入/擦除的情况下重复搜索的情况,有时使用排序向量(使用标准算法搜索)可能是最快的。这具有单个连续内存分配的优势,这对缓存更加友好。它总是优于
map
,但
unordered\u map
可能仍然更快-如果您愿意,请进行测量。

map:

插入:

  • 对于第一版(插入(x)),对数 <