English 中文(简体)
我怎么能估计内存使用std::地图吗?
原标题:
  • 时间:2009-04-06 07:39:01
  •  标签:

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

但是是什么因素?不同的公式可能吗?

也许容易要求上限?

最佳回答

估计会更接近

(sizeof(A) + sizeof(B) + ELEMENT_OVERHEAD) * N + CONTAINER_OVERHEAD

有一个为每个元素添加开销,也有一个固定的开销维持用于数据结构存储的数据结构映射。这通常是一个二叉树,如< a href = " http://en.wikipedia.org/wiki/Red_Black_Tree " rel = " noreferrer " > < / >红黑树。例如,在海湾合作委员会c++ STL实现<代码> ELEMENT_OVERHEAD将<代码> < /代码> sizeof (_Rb_tree_node_base) < /代码>和<代码> CONTAINER_OVERHEAD将<代码> < /代码> sizeof (_Rb_tree) > < /代码。上面的图你也应该增加的开销内存管理结构用于存储地图元素。

它年代可能更容易到达估计通过测量代码为各种大型集合s内存消耗。

问题回答

您可以使用< a href = " http://www.almostinfinite.com/memtrack.html " rel = " noreferrer " > MemTrack < / >,柯蒂斯Bartley。这年代一个替换默认的内存分配器,可以跟踪内存使用分配的类型。

输出的一个例子:

-----------------------
Memory Usage Statistics
-----------------------

allocated type                        blocks          bytes  
--------------                        ------          -----  
struct FHRDocPath::IndexedRec          11031  13.7% 2756600  45.8%
class FHRDocPath                       10734  13.3%  772848  12.8%
class FHRDocElemPropLst                13132  16.3%  420224   7.0%
struct FHRDocVDict::IndexedRec          3595   4.5%  370336   6.2%
struct FHRDocMDict::IndexedRec         13368  16.6%  208200   3.5%
class FHRDocObject *                      36   0.0%  172836   2.9%
struct FHRDocData::IndexedRec            890   1.1%  159880   2.7%
struct FHRDocLineTable::IndexedRec       408   0.5%  152824   2.5%
struct FHRDocMList::IndexedRec          2656   3.3%  119168   2.0%
class FHRDocMList                       1964   2.4%   62848   1.0%
class FHRDocVMpObj                      2096   2.6%   58688   1.0%
class FHRDocProcessColor                1259   1.6%   50360   0.8%
struct FHRDocTextBlok::IndexedRec        680   0.8%   48756   0.8%
class FHRDocUString                     1800   2.2%   43200   0.7%
class FHRDocGroup                        684   0.8%   41040   0.7%
class FHRDocObject * (__cdecl*)(void)     36   0.0%   39928   0.7%
class FHRDocXform                        516   0.6%   35088   0.6%
class FHRDocTextColumn                   403   0.5%   33852   0.6%
class FHRDocTString                      407   0.5%   29304   0.5%
struct FHRDocUString::IndexedRec        1800   2.2%   27904   0.5%

如果你真的想知道运行时内存占用,使用一个定制的分配器,通过在创建地图。看到Josuttis书,< a href = " http://www.josuttis.com/libbook/memory/myalloc.hpp.html " rel = " noreferrer " > < / >页面(用于自定义分配器)。

也许容易要求上限?

上限取决于准确的实现(例如,平衡树的特殊变体使用)。也许,你可以告诉我们为什么需要这个信息我们可以帮助更好?

最近我需要为自己回答这个问题,并简单地写了一个小基准程序使用std::地图我MSVC 2012年64位模式下编译。

地图与吸收~ 15 gb 1.5亿节点,这意味着8字节,8字节R, 8字节整数键,和8字节数据,共计32字节,吸收<强>大约2/3的映射内存内部节点,离开三分之树叶。< /强>

就我个人而言,我发现这是令人惊讶的是可怜的记忆效率,但这是它是什么。

希望这是一个方便的经验法则。

PS:的开销std::地图是AFAICT单个节点的大小。

公式更像:

(sizeof(A) + sizeof(B) + factor) * N

因素是每项开销。c++映射通常实现为“红-黑”树。这些是二叉树,所以将会有至少两个指针的左/右节点。也将有可能实现的东西——一个父指针和一个“颜色”指标,所以因素可能是类似的

(sizeof( RBNode *) * 3 + 1) / 2

然而,这一切都是高度依赖实现——你真的需要检查才能确定自己的库实现的代码。

我也寻找一些计算的大小<代码> std::地图> < /代码。我试图解释< a href = " https://stackoverflow.com/a/720520/5735010 " > Diomidis卢卡雷利< / > s回答和扩大他的答案在这里可以帮助他人。

我在扩大他的答案通过添加几行代码。

#include <bits/stl_tree.h>
int main(int argc, char *argv[])
{
    std::cout << sizeof(std::_Rb_tree_node_base) << std::endl;
    return 0;
}

输出(在我的胳膊皮层9 iMX6Solo-X处理器运行Linux[4.9.175]和编译器:<代码> arm-fslc-linux-gnueabi-gcc (GCC) 7.3.0 > < /代码):

16

考虑<代码> std:: map < A、B > < /代码>,我感兴趣的大小<代码> ELEMENT_OVERHEAD > < /代码,因为它生长线性的元素出现在地图上。ELEMENT_OVERHEAD被发现相当于<代码> sizeof (std:: _Rb_tree_node_base) > < /代码,因此系统的值为16。

(sizeof(A) + sizeof(B) + ELEMENT_OVERHEAD) * N + CONTAINER_OVERHEAD

地图的大小取决于地图的实现。你可能有不同的大小在不同的编译器/平台上,这取决于STL实现他们提供。

你为什么需要这个尺寸吗?





相关问题
热门标签