繁体   English   中英

小N的std :: map vs unordered_map内存占用

[英]std::map vs unordered_map memory footprint for small N

对于内存使用比速度更受关注的嵌入式系统应用程序,最好使用的地图容器是什么? std::mapstd::unordered_map 这适用于N小于100的情况。

如果实现很重要,那么我关心的是libstdc ++实现(GCC)。

虽然我知道打破一个简单的内存使用数组是不可能的,但我想避免使用具有O(N)性能的数据结构。 因此,虽然我想减少内存占用,但我也希望查找速度合理(优于O(N))。 我不关心其他操作(插入,删除),因为它们不经常发生。

如果我想进行自己的内存使用测量,我将如何在Linux平台上进行此操作?

boost :: flat_map是否适合作为一个关联容器,占用空间小,查找时间比O(n)好?

对于小N,排序的向量通常是最快的容器,并且具有最小的内存占用。 boost :: flat_map是一个实现,其他人称之为AssociativeVector。 您可以使用std::lower_bound轻松实现它。 由于必须对数据进行排序,因此插入和删除操作是O(n),因为数据必须在向量中移位。

使用排序向量,您可以执行二进制搜索,即O(log N)以进行检索。 std::lower_bound的复杂性是:

执行的比较次数在第一个和最后一个之间的距离是对数的(最多log2(最后 - 第一个)+ O(1)比较)

作为我对vector答案的替代方案,如果您事先知道密钥,也可以考虑哈希映射。 您可以使用gperf生成完美的哈希函数,然后进行O(1)查找。 实际速度取决于密钥类型。 我见过std::map<string>表现优于std::unordered_map<string>因为std::unordered_map<string>的哈希函数必须处理完整的键字符串,而地图比较函数经常在前几个字符后停止。

如果速度很重要,请同时实施和基准。 对于堆分析,我过去使用过google perftools

如果插入和删除不经常发生,那么为什么不使用排序的std::vectorstd::lower_boundstd::equal_range进行查找,而不是std::mapstd::unordered_map ,你得到ln(N)速度查找和最小空间。 boost::flat_map提供了一个很好的关联容器API,它以这种方式实现。 这里这里提供一些详细的基准。 另一种选择是开放地址哈希表。 你必须做一些实验,看看这是否能满足你的内存限制,并且仍然比ln(N)更快地进行查找。 两种解决方案都提供了良好的局部性,但是如果你想要零内存开销并且ln(N)足够快以便查找,那么我将使用已排序的数组。

除了有序矢量(如boost::flat_map )之外,您还可以查看google::dense_hash_map ,它是一个哈希映射,存储与std::unordered_map相邻的数据,它分别分配节点。 价格是需要专用的空键值和缺少迭代器失效保证。 还有一个更紧凑的google::sparse_hash_map (虽然速度较慢)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM