使用 unordered_map 时的内存分配
Memory allocations when using unordered_map
如果 std::unordered_map<int,...>
保持大致相同的大小但不断添加和删除项目,它是否会不断分配和释放内存或缓存并重用内存(即像池或向量一样)?假设库的现代标准 MS 实现。
标准没有具体说明这些方面,因此它们是实现定义的。最值得注意的是,像您描述的缓存行为通常是通过使用 自定义分配器 (例如 memory pool allocator)实现的,因此它通常应该与容器实现分离。
the standard, ~p874关于无序容器的相关位:
The elements of an unordered associative container are organized into
buckets. Keys with the same hash code appear in the same bucket. The
number of buckets is automatically increased as elements are added to
an unordered associative container, so that the average number of
elements per bucket is kept below a bound.
并插入:
The insert and emplace members shall not affect the validity of
iterators if (N+n) <= z * B, where N is the number of elements in the
container prior to the insert operation, n is the number of elements
inserted, B is the container’s bucket count, and z is the container’s
maximum load factor
您可以从字里行间看出,由于迭代器的有效性不受影响,因此可能不会进行内存分配。虽然这绝不是保证(例如,如果桶数据结构是一个链表,你可以附加到它而不会使迭代器失效)。该标准似乎没有指定删除元素时应该发生什么,但由于它无法使上面的约束无效,我看不出有理由取消分配内存。
确定您的具体实施的最简单方法是阅读源代码或分析您的代码。
或者,您可以尝试通过使用 rehash
和 resize
方法并调整地图的 load_factor.
来控制此行为(如果您确实需要)
如果 std::unordered_map<int,...>
保持大致相同的大小但不断添加和删除项目,它是否会不断分配和释放内存或缓存并重用内存(即像池或向量一样)?假设库的现代标准 MS 实现。
标准没有具体说明这些方面,因此它们是实现定义的。最值得注意的是,像您描述的缓存行为通常是通过使用 自定义分配器 (例如 memory pool allocator)实现的,因此它通常应该与容器实现分离。
the standard, ~p874关于无序容器的相关位:
The elements of an unordered associative container are organized into buckets. Keys with the same hash code appear in the same bucket. The number of buckets is automatically increased as elements are added to an unordered associative container, so that the average number of elements per bucket is kept below a bound.
并插入:
The insert and emplace members shall not affect the validity of iterators if (N+n) <= z * B, where N is the number of elements in the container prior to the insert operation, n is the number of elements inserted, B is the container’s bucket count, and z is the container’s maximum load factor
您可以从字里行间看出,由于迭代器的有效性不受影响,因此可能不会进行内存分配。虽然这绝不是保证(例如,如果桶数据结构是一个链表,你可以附加到它而不会使迭代器失效)。该标准似乎没有指定删除元素时应该发生什么,但由于它无法使上面的约束无效,我看不出有理由取消分配内存。
确定您的具体实施的最简单方法是阅读源代码或分析您的代码。
或者,您可以尝试通过使用 rehash
和 resize
方法并调整地图的 load_factor.