2012-08-04 79 views
5

它在内部被视为一个数组或被CLR视为完全不同的类型吗?列表<T>如何内部映射?

我想实现整数值的列表。

List<int> lst = new List<int>(); 
lst.Add(3); 
lst.Add(4); 

创建整数

int[] arr = new int[2]; 
arr[0] = 3; 
arr[1] = 4; 

阵列返回更好的时间跨度结果的数组。那么为什么人们更喜欢List <>。

+2

你可以试试[ILSpy](http://ilspy.net)并自己看看。具有动态可扩展/可收缩列表的原因是它不是像'Array'那样的固定大小。 – 2012-08-04 09:47:00

回答

5

List<>是一个数据结构的实现,它负责按需分配内存;它允许在任何索引处插入和删除等,因此它比简单的数组更方便。

在引擎盖下,目前的List<>实现使用一个数组进行存储,并且在进行类似数组操作时的开销很小。增加的便利性通常值得一点(如果相关的话)性能差异。添加项目通常更快,因为列表分配内存块,并且不需要每次添加都有新的分配和复制(与纯数组相比,Length始终与内存中的大小绑定在一起)。

+0

所以,你说的是,尽管可以忽略不计,'List <>'将提供一个较慢的响应,就_Speed_而言,而不是'Array'? – 2012-08-04 10:04:52

+2

当然。列表是一个数组抽象概念,并且抽象会花费额外的CPU周期。不过,在正常情况下,我同意Lucero的观点,List的速度还不够快。 – Steven 2012-08-04 10:09:37

+2

“响应时间”通常是不相关的,请求会在(快速且便宜的)边界检查之后传递到底层数组。这可能甚至会被运行时内联,所以它甚至不需要额外的调用。 – Lucero 2012-08-04 10:29:57

1

正常的随机访问列表通常有一个内部数组。 .NET List<T>执行此操作。其他实现,如LinkedList<T>使用元素链而不是数组。更奇特的列表可能会在内部使用树来进行排序。

List<T>中的内部数组初始化的长度很短(4我相信),并且如果尝试在数组的最大范围外进行添加,它将被展开。由于这可能非常耗时(需要复制数组),因此数组的大小加倍,即添加第5个元素时,内部数组的大小调整为8,依此类推。

+0

我记得读过,'List <>'数据结构针对_Speed_进行了优化,而'Array' DS针对_Memory_进行了优化。你似乎违背了'List <>'为_Speed_优化的事实。 (当我们说它被重新调整大小和重新分配,当移出界限时) – 2012-08-04 10:01:10

+0

我不同意这种区别。列表内部有一个数组,因此与数组存储方式基本上没有区别。你用清单付出了很小的性能损失,并且为此付出了一个动态/可调整大小的集合。所以总之,列表和数组之间最大的不同之处在于,你总是可以将东西添加到列表中。 – 2012-08-04 10:05:23

+1

@bugbuster,如果你想添加一个项目到一个数组(这样'Length'增加,也就是说,不仅仅是改变现有项目),你也必须重新分配数组。该列表将以更大的块形式生长,并跟踪数组中使用的元素的数量,因此对于顺序添加而言,速度更快。 – Lucero 2012-08-04 10:27:29