最近我遇到了在llvm中广泛使用的DenseMap数据结构。我认为它是std::map(?)
的某种优化版本。谁能帮我理解它们之间的区别或相似之处?
答案 0 :(得分:2)
llvm::DenseMap
是std::unordered_map
,所以它不太意味着取代std::map
更换(至少不是如果你仔细地根据所选择的有序与无序性)。
与std::unordered_map
不同,std::map
保证容器的迭代顺序与插入顺序匹配。在许多情况下,您并不关心迭代顺序...但是在少数情况下,DenseMap
并不是一个选择。
现在,为了对比DenseMap
与std::unordered_map
:不像std
容器,DenseMap
保存在一个存储器中分配的所有数据,并将其与赞成水桶摒弃将键和值彼此相邻地保存在内存中。这两个特征都为一个大赢data locality,因此速度在几乎所有的上下文中。
此外,DenseMap
默认情况下会分配大量的键/值对(实际上是64个),因此在较小的大小下,插入几乎是免费的。当然,这样做的缺点是,如果要创建很多非常小的地图,或者您自己的类型很大,则内存效率低下;如果您的容器将永远不会增长到64个元素,你在浪费内存。根据您的用例,实际上可能不会伤害您。
与std::unordered_map
相比,最后的区别可以使某些人措手不及:插入{em> 后DenseMap
的迭代器将无效(与std::map
和{ {1}},其中,如果发生高速缓存重散列的迭代仅无效)。这在我看来主要是一个理论问题,因为您当然可以只存储密钥而不是迭代器。 (而且与向量不同,找到保留地图迭代器的真实代码并不常见。)
如果您想在自己的计算机上运行基准测试,我将benchmarks与std::unordered_map
容器与DenseMap
容器进行了比较,还有a GitHub repo 。四个选定图是下面,示出用于在不同尺寸的地图插入和随机查找速度。
<强>插入速度在小地图强>
<强>插入速度在大地图强>