对于内存使用比速度更重要的嵌入式系统应用程序,最好使用的地图容器是什么? std::map
,std::unordered_map
?这适用于N
小于百分之一的情况。
如果实施很重要,那么我就关注libstdc ++实现(GCC)。
虽然我知道在内存使用方面无法击败简单数组,但我想避免使用具有O(N)性能的数据结构。因此,虽然我想减少内存占用,但我还希望查找速度合理(优于O(N))。我不关心其他操作(插入,移除),因为它们不经常发生。
如果我想进行自己的内存使用量测量,我将如何在Linux平台上进行此操作?
boost::flat_map是否适合作为一个关联容器,占用空间小,查找时间优于O(n)?
答案 0 :(得分:3)
对于小N,有序矢量通常是最快的容器,并且具有最小的内存占用。 boost :: flat_map是一个实现,其他人称之为AssociativeVector。您可以使用std::lower_bound
轻松实现它。由于必须对数据进行排序,因此插入和删除操作为O(n),因为数据必须在向量中移位。
使用排序向量,您可以执行二进制搜索,即O(log N)以进行检索。 std::lower_bound
的复杂性是:
执行的比较次数在第一个和最后一个之间的距离是对数的(最多log2(最后一个)+ O(1)比较)
答案 1 :(得分:3)
作为替代my answer on vector
,如果您事先知道密钥,也可以考虑哈希映射。您可以使用gperf生成完美的哈希函数,然后进行O(1)查找。实际速度取决于密钥类型。我已经看到std::map<string>
的结果优于std::unordered_map<string>
的情况,因为字符串的哈希函数必须处理完整的键字符串,而地图比较函数通常在前几个字符后停止。
如果速度很重要,请同时执行和基准测试。对于堆分析,我过去使用过google perftools。
答案 2 :(得分:2)
如果不经常发生插入和删除,那么为什么不使用排序的std::map
和std::unordered_map
或std::vector
进行查找,而不是std::lower_bound
或std::equal_range
。你获得ln(N)
的查找速度和最小的空间。 boost::flat_map
提供了一个很好的关联容器API,它以这种方式实现。一些详细的基准测试是here和here。另一种选择是开放地址哈希表。您必须进行一些实验,以确定这是否会满足您的内存限制,并且仍然比ln(N)
提供更快的查找速度。两种解决方案都提供了良好的局部性,但是如果你想要零内存开销并且ln(N)
对于查找来说足够快,那么我将使用已排序的数组。
答案 3 :(得分:2)
除了排序向量(如boost::flat_map
)之外,您还可以查看google::dense_hash_map
,它是一个哈希映射,存储与std::unordered_map
相邻的数据,它分配节点分别。价格是需要专用的空键值和缺少迭代器失效保证。还有一个更紧凑的google::sparse_hash_map
(虽然更慢)。