繁体   English   中英

在内存使用方面,c ++中的map和unordered_map有什么区别吗?

[英]Is there any difference between map and unordered_map in c++ in terms of memory usage?

我在InterviewBit上解决了一个问题并遇到了一个问题,这里是链接https://www.interviewbit.com/problems/diffk-ii/ 当我使用c ++ STL map来解决这个问题时,它会向我显示消息

内存限制超出。 您的提交未在分配的内存限制中完成。 这是我的代码

int Solution::diffPossible(const vector<int> &A, int B) {
    int n = A.size();
    map< int , int > mp;
    for(int i =0;i<n; i++)
        mp[A[i]] = i;
    int k = B;
    for(int i =0; i<n; i++){
        if(mp.find(A[i]+k) != mp.end() && mp[A[i]+k] != i){
            return 1;
        }
        if(mp.find(A[i]-k) != mp.end() && mp[A[i]-k] != i){
            return 1;
        }
    }

    return 0;
}

当我用unorderd_map解决方案替换map时接受了。 这是代码

int Solution::diffPossible(const vector<int> &A, int B) {
    int n = A.size();
    unordered_map< int , int > mp;
    for(int i =0;i<n; i++)
        mp[A[i]] = i;
    int k = B;
    for(int i =0; i<n; i++){
        if(mp.find(A[i]+k) != mp.end() && mp[A[i]+k] != i){
            return 1;
        }
        if(mp.find(A[i]-k) != mp.end() && mp[A[i]-k] != i){
            return 1;
        }
    }

    return 0;
}

这意味着map比unordered_map占用更多内存。 任何人都可以解释这是怎么回事? 为什么map比unordered_map占用更多的内存空间?

  1. 映射被实现为二进制搜索树,并且每个节点(除了有用数据之外)通常存储3个指针 (对于左子节点,右子节点和父节点)。

  2. 无序映射实现为哈希表 ,其中每个节点都在链表中。 在单链表(属于相关桶)的情况下,每个节点只有1个指针 更新 :但是,每个存储桶还有一个额外的指针。 在没有冲突的理想情况下,每个元素存储2个指针存储在内存中。

注意,2个int通常占用8个字节,与单个指针相同。


例如,查看GNU libstdc ++实现。 RB树的节点定义如下:

struct _Rb_tree_node_base
{
  typedef _Rb_tree_node_base* _Base_ptr;
  typedef const _Rb_tree_node_base* _Const_Base_ptr;

  _Rb_tree_color    _M_color;
  _Base_ptr     _M_parent;
  _Base_ptr     _M_left;
  _Base_ptr     _M_right;
  ...

在那里,你可以观察到这三个指针。


通常,很难说哪个容器会消耗更少的总体内存。 但是,我创建了一个基准,将1M随机数插入到两个容器中并测量最大驻留大小 (MaxRSS)以反映所有消耗的内存空间,包括例如堆内务数据。 结果如下:

  1. 48,344 kB for std::map
  2. 50 888 kB for std::unordered_map
  3. 40,932 kB for std::unordered_map with reserve

请注意,由于存储桶列表的重新分配,无序映射(广告2)的内存消耗较高。 这就是reserve会员职能的用途。 如果一个人关心内存消耗并事先知道元素的数量,他/她应该总是预先分配(这与向量的情况相同)。

映射基本上是二叉搜索树,而unordered_map实现为哈希映射。 如果你看看两者的实现,你会很快注意到BST要大得多。

这也意味着map比unordered_map慢很多。

                | map             | unordered_map
---------------------------------------------------------
Ordering        | increasing  order   | no ordering
                | (by default)        |

Implementation  | Self balancing BST  | Hash Table
                | like Red-Black Tree |  

search time     | log(n)              | O(1) -> Average 
                |                     | O(n) -> Worst Case

Insertion time  | log(n) + Rebalance  | Same as search

Deletion time   | log(n) + Rebalance  | Same as search

BST:

struct node
{
    int data;
    node* left;
    node* right;
};

HashMap的:

struct hash_node {
    int key;
    int value;
    hash_node* next;
}

参考: https//www.geeksforgeeks.org/map-vs-unordered_map-c/

暂无
暂无

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

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