再谈c#的list,从底层实现原理来分析,以及简单的优化

优化 同时被 2 个专栏收录
2 篇文章 0 订阅
6 篇文章 0 订阅

因为最近经常用到list,所以对它可以动态调节长度很感兴趣,决定一探究竟,结果还真发现了一些有意思的东西;

大家看下面的代码:

 List<int> list = new List<int>();
 Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
 list.Add(1);
 Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
 list.Add(2);
 Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
 list.Add(3);
 list.Add(4);
 Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
 list.Add(5);
 Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
 list.Add(6);
 list.Add(7);
 list.Add(8);
 list.Add(9);
 Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);

他的执行结果是:

我们发现当你没有元素的时候它的list长度为0;

添加第一个元素之后它的长度变成了4个;当添加第五个元素的时候它的表长达到了八个,在添加到第九个元素的时候它的list表长变成了16.

由此我们可以推断,他并不是真正意义上的可自由添加删除数据,list表也有自己的长度,

经过翻阅一些资料,以及看了c#的源代码,发现:

list在新建表之后的初始长度为0,添加第一个元素之后会生成一个长度为四的表,也就是初始长度

每此添加数据的时候会判断是否超出表长,如果超出表长那么就新建一个list表(这个表的长度是原来表的二倍),

然后list表会把之前的表数据复制到新表

但是之前的表去了哪里呢,在这里我推测,他复制表之后,他直接把指针指向了新的表,并没有管当前的表,所以当前的表会变成内存垃圾等着cg回收

 

那么我们怎么优化list来提高效率呢,其实我们可以自定义表的长度

像这个样子:

//定义list长度
List<int> list = new List<int>(1);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(1);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(2);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(3);
list.Add(4);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(5);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Add(6);
list.Add(7);
list.Add(8);
list.Add(9);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);
list.Remove(9);
list.Remove(8);
Console.WriteLine("list当前长度:" + list.Capacity + ";list有效长度" + list.Count);

他的结果是这个样子,也从侧面的反映了我们的结论。

 

那么为什么我推荐我们建立list表的时候自定义表的大小呢,

因为我们自定义list表的大小之后可以防止两个事情发生:

1.频繁的添加数据造成的内存垃圾。

2.由于表过于巨大,再次超出表的上限时会出现巨大的内存占用。而且里面还是空数据,根本用不上。

 

题外话:我们今天讨论的是c#的list,为什么这么说呢

因为在查阅资料的时候,我发现c#的list和java的list完全不是一个东西,对于java来说list是一个接口,他的初始长度是10,每次增长长度是之前的1.5倍。

而c#的list和arraylist实现的都是ilist接口,初始长度和每次超级加倍的倍数也不一样。、

 

 

 

  • 2
    点赞
  • 1
    评论
  • 3
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 1 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页

打赏作者

ACDC_WOOO

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值