For example, I have a std::map with known sizeof(A) and sizeof(B), while map has N entries inside. How would you estimate its memory usage? I'd say it's something like
(sizeof(A) + sizeof(B)) * N * factor
But what is the factor? Different formula maybe?
Maybe it's easier to ask for upper bound?
The estimate would be closer to
There is an overhead for each element you add, and there is also a fixed overhead for maintaining the data structure used for the data structure storing the map. This is typically a binary tree, such as a Red-Black Tree. For instance, in the GCC C++ STL implementation
ELEMENT_OVERHEAD
would besizeof(_Rb_tree_node_base)
andCONTAINER_OVERHEAD
would besizeof(_Rb_tree)
. To the above figure you should also add the overhead of memory management structures used for storing the map's elements.It's probably easier to arrive at an estimate by measuring your code's memory consumption for various large collections.
The size of the map really depends on the implementation of the map. You might have different sizes on different compilers/platforms, depending on which STL implementation they are providing.
Why do you need this size?
The formula is more like:
where factor is the per entry overhead. C++ maps are typically implemented as red-black trees. These are binary trees, so there will be at least two pointers for the left/right nodes. There will also be some implementation stuff - probably a parent pointer and a "colour" indicator, so factor may be something like
However, all this is highly implementation dependent - to find out for sure you really need to examine the code for your own library implementation.
I recently needed to answer this question for myself, and simply wrote a small benchmark program using std::map I compiled under MSVC 2012 in 64-bit mode.
A map with 150 million nodes soaked up ~ 15GB, which implies the 8 byte L, 8 byte R, 8 byte int key, and 8 byte datum, totaling 32 bytes, soaked up about 2/3rds of the map's memory for internal nodes, leaving 1/3rd for leaves.
Personally, I found this to be surprisingly poor memory efficiency, but it is what it is.
Hope this makes for a handy rule-of-thumb.
PS: The overhead of a std::map is that of a single node's size AFAICT.
You could use MemTrack, by Curtis Bartley. It's a memory allocator that replaces the default one and can track memory usage down to the type of allocation.
An example of output:
If you really want to know the runtime memory footprint, use a custom allocator and pass it in when creating the map. See Josuttis' book and this page of his (for a custom allocator).
The upper bound will depend on the exact implementation (e.g. the particular variant of balanced tree used). Maybe, you can tell us why you need this information so we can help better?