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

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

大家看下面的代码:

 List list = new List();
 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);

他的执行结果是:

再谈c#的list,从底层实现原理来分析,以及简单的优化_第1张图片

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

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

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

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

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

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

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

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

 

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

像这个样子:

//定义list长度
List list = new List(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);

再谈c#的list,从底层实现原理来分析,以及简单的优化_第2张图片

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

 

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

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

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

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

 

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

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

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

 

 

 

你可能感兴趣的:(优化,奇妙方法,c#,unity3d)