简体   繁体   中英

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

I am solving a problem on InterviewBit and come across a question, here's link https://www.interviewbit.com/problems/diffk-ii/ . When I have used c++ STL map to solve this problem, it shows me the message

Memory Limit Exceeded. Your submission didn't complete in the allocated memory limit. here's my code

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;
}

and when I have replaced map by unorderd_map solution accepted. Here's code

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;
}

It means map is taking more memory than unordered_map. Can anyone explain how this is happening? Why map is taking more memory space than unordered_map?

  1. Maps are implemented as binary search trees and each node (additionally to useful data) typically stores 3 pointers (to a left child, a right child, and a parent).

  2. Unordered maps are implemented as hash tables , where each node is in a linked list. In case of a singly linked list (that belongs to a relevant bucket), there is only 1 pointer per node. UPDATE : However, there is also an additional pointer for each bucket. In an ideal case where there are no collisions, there would be 2 pointers per element stored in memory.

Note that 2 int s will typically occupy 8 bytes, same as a single pointer.


For example, look at the GNU libstdc++ implementation. The RB tree's node is defined as follows:

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;
  ...

There, you can observe those 3 pointers.


Generally, it's hard to say which container will consume less overall memory. However, I created a benchmark to insert 1M random numbers into both containers and measured maximum resident size (MaxRSS) to reflect all the consumed memory space including, eg, heap housekeeping data. The results were as follows:

  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 .

Note that the memory consumption for the unordered map (ad 2.) was higher due to reallocations of bucket lists. That is what reserve member function is for. If one cares about memory consumption and knows the number of elements beforehand, he/she should always preallocate (this is the same situation as for vectors).

A map is basically a binary search tree, while unordered_map is implemented as hash map. If you look at implementations of both, you'll quickly notice that a BST is quite a bit bigger.

It also means that map is a lot slower than 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;
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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