Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing a std::map when the size is known in advance

I would like to initialize a std::map. For now I am using ::insert but I feel I am wasting some computational time since I already know the size I want to allocate. Is there a way to allocate a fixed size map and then fill the map ?

like image 200
vanna Avatar asked Oct 24 '12 12:10

vanna


People also ask

How do you initialize a map with 0?

What exactly do you want to initialize to zero? map's default constructor creates empty map. You may increase map's size only by inserting elements (like m["str1"]=0 or m. insert(std::map<std::string,int>::value_type("str2",0)) ).

How do you initialize a map with default value?

To initialize the map with a random default value below is the approach: Approach: Declare a structure(say struct node) with a default value. Initialize Map with key mapped to struct node.

How do I change the size of a map in CPP?

map::size() function is an inbuilt function in C++ STL, which is defined in header file. size() is used to check the size of the map container. This function gives size or we can say gives us the number of elements in the map container associated.


2 Answers

No, the members of the map are internally stored in a tree structure. There is no way to build the tree until you know the keys and values that are to be stored.

like image 113
Bo Persson Avatar answered Sep 21 '22 18:09

Bo Persson


The short answer is: yes, this is possible, but it's not trivial. You need to define a custom allocator for your map. The basic idea is that your custom allocator will set aside a single block of memory for the map. As the map requires new nodes, the allocator will simply assign them addresses within the pre-allocated block. Something like this:

std::map<KeyType, ValueType, std::less<KeyType>, MyAllocator> myMap;  myMap.get_allocator().reserve( nodeSize * numberOfNodes ); 

There are a number of issues you'll have to deal with, however.

First, you don't really know the size of each map node or how many allocations the map will perform. These are internal implementation details. You can experiment to find out, but you can't assume that the results will hold across different compilers (or even future versions of the same compiler). Therefore, you shouldn't worry about allocating a "fixed" size map. Rather, your goal should be to reduce the number of allocations required to a handful.

Second, this strategy becomes quite a bit more complex if you want to support deletion.

Third, don't forget memory alignment issues. The pointers your allocator returns must be properly aligned for the various types of objects the memory will store.

All that being said, before you try this, make sure it's necessary. Memory allocation can be very expensive, but you still shouldn't assume that it's a problem for your program. Measure to find out. You should also consider alternative strategies that more naturally allow pre-allocation. For example, a sorted list or a std::unordered_map.

like image 33
Peter Ruderman Avatar answered Sep 22 '22 18:09

Peter Ruderman