admin管理员组文章数量:1611925
我们知道C#中的容器,其基础规则是以2倍的翻倍策略进行内存扩增的,我们也经常会通过统计容器的Capacity来统计内存占用。像List这种简单的线性结构。Capacity作为公开的属性是直接可以获取到的。但是像Dictionary这种复杂结构,我们不能直接拿到Capacity属性,那怎么办呢,我们可以通过反射的方法,简单计算下内存占用。
我们只统计了桶的大小,并没有统计Entry的大小,感兴趣的同学可以自己试一下
Dictionary<int, int> dic = new Dictionary<int, int>();
for (int i = 0; i < 63; ++i)
{
dic.Add(i, i);
}
Type dicType = dic.GetType();
FieldInfo info = dicType.GetField("buckets", BindingFlags.Instance | BindingFlags.NonPublic);
object t = info.GetValue(dic);
Type arrayType = t.GetType();
PropertyInfo p = arrayType.GetProperty("Length", BindingFlags.Instance | BindingFlags.Public);
int length = (int) p.GetValue(t);
length.Print();
这个结果是89,因为它需要保证桶的大小是质数
其中还有一个有趣的问题,如果你看过C#字典的源代码可以知道,C#Entry底层维护的是一个静态链表。通常静态链表会有一个head和一个free分别指向已经分配的链表头和可用的节点链表。C#源码中很巧妙,它并没有在初始化中构建free链表。而是初始化为0.当free没有可用节点的时候,总是拿取head.Length的下一个位置作为新的可用节点。这样就省去了初始化free链表的消耗。
这块没有仔细解释,感兴趣的同学,如果对静态链表有概念的话,可以自己体会一下。
下边贴上C# 字典官方源代码实现地址:
Reference Source
本文标签: dictionaryCapacity
版权声明:本文标题:C# 中 Dictionary 的 Capacity 问题 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1728619477a1166162.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论