I really dislike comments when code could be used, i.e. when I see sizeof(void*)
, it doesn’t tell me anything about what we’re actually measuring … 2 * sizeof(void*)
is even worse.
I was thinking of showing exactly what we’re measuring here, something like:
0
1// Empirically, an std::unordered_map node has two pointers (likely
2// forward and backward pointers) on some platforms (Windows and macOS),
3// so be conservative in estimating memory usage by assuming this is
4// the case for all platforms.
5template <typename X>
6struct unordered_node : private X
7{
8 void* next_ptr;
9 void* prev_ptr;
10};
11
12// The memory used by an unordered_set or unordered_map is the sum of the
13// sizes of the individual nodes (which are separately allocated) plus
14// the size of the bucket array (which is a single allocation).
15// Empirically, each element of the bucket array consists of two pointers
16// on some platforms (Windows and macOS), so be conservative.
17template <typename X, typename Y>
18static size_t DynamicUsage(const std::unordered_set<X, Y>& s)
19{
20 return MallocUsage(sizeof(unordered_node<X>)) * s.size() +
21 MallocUsage((sizeof(unordered_node<X>::next_ptr) + sizeof(unordered_node<X>::prev_ptr)) * s.bucket_count());
22}
23
24template <typename X, typename Y, typename Z>
25static size_t DynamicUsage(const std::unordered_map<X, Y, Z>& m)
26{
27 return MallocUsage(sizeof(unordered_node<std::pair<const X, Y>>)) * m.size() +
28 MallocUsage((sizeof(unordered_node<std::pair<const X, Y>>::next_ptr) + sizeof(unordered_node<std::pair<const X, Y>>::prev_ptr)) * m.bucket_count());
29}
Also note that the current test doesn’t doesn’t exercise these modified lines at all, so we’ve kinda’ in the dark here…