C# 中 Dictionary 的 Capacity 问题

我们知道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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值