C# c中字符串数组和字符串列表的区别是什么#

C# c中字符串数组和字符串列表的区别是什么#,c#,arrays,string,C#,Arrays,String,我听说阵列比集合快 你能告诉我string[]比列表快多少吗。数组是比列表之类的集合更低级的抽象。CLR直接了解数组,因此迭代、访问等所涉及的工作稍微少一些 然而,这几乎不应该规定您实际使用的是什么。在大多数实际应用中,性能差异可以忽略不计。我很少发现使用数组而不是各种泛型集合类是合适的,并且确实有些人认为。一个显著的缺点是没有不可变数组(除了空数组)。。。而您可以相对轻松地通过API公开只读集合。数组的大小不可调整。这意味着当它被创建时,会分配一个内存块,其大小足以容纳您指定的任意多个元素 另

我听说阵列比集合快


你能告诉我
string[]
列表快多少吗。

数组是比列表之类的集合更低级的抽象。CLR直接了解数组,因此迭代、访问等所涉及的工作稍微少一些


然而,这几乎不应该规定您实际使用的是什么。在大多数实际应用中,性能差异可以忽略不计。我很少发现使用数组而不是各种泛型集合类是合适的,并且确实有些人认为。一个显著的缺点是没有不可变数组(除了空数组)。。。而您可以相对轻松地通过API公开只读集合。

数组的大小不可调整。这意味着当它被创建时,会分配一个内存块,其大小足以容纳您指定的任意多个元素

另一方面,
列表
可以隐式调整大小。每次添加项时,框架可能需要分配更多内存来保存刚刚添加的项。这是一个昂贵的操作,所以我们最后说“列表比数组慢”


当然,这是一个非常简单的解释,但希望足以说明问题。

数组是最简单的集合形式,因此它比其他集合更快。列表(和许多其他集合)实际上在内部使用数组来保存其项


当然,数组也受到其简单性的限制。最值得注意的是,您不能更改数组的大小。如果你想要一个动态的集合,你可以使用一个列表。

这篇文章是从2004年开始的,这意味着它是关于并且没有泛型的。 阵列与集合的性能实际上在当时是个问题,因为集合类型导致了大量exta装箱取消装箱操作。但自从.net 2.0引入泛型以来,性能上的差异几乎消失了。

List
是一个带有私有成员的类,它是一个
字符串[]
。MSDN文档在几个地方说明了这一事实。List类基本上是一个围绕数组的包装类,它为数组提供了其他功能

哪个更快的答案取决于您试图对列表/数组执行的操作。对于访问和为元素赋值,数组的速度可能快得可以忽略,因为列表是数组的抽象(正如Jon Skeet所说)

如果您打算拥有一个随时间增长的数据结构(获得越来越多的元素),那么性能(平均速度)方面的列表将开始闪亮。这是因为每次调整数组大小以添加另一个元素时,都是O(n)操作。当您将一个元素添加到一个列表中(并且该列表已经满负荷)时,该列表的大小将加倍。我不会深入讨论细节,但基本上这意味着增加列表的大小平均是一个O(logn)操作。当然,这也有缺点(如果只超出最后一个容量几项,您可能会得到实际需要的几乎两倍的内存分配量)


编辑:我在上面的段落中有点搞混了。正如Eric在下面所说的,列表的大小调整次数是O(logn),但调整数组大小的实际成本分摊到O(1)。

array.Resize()在更改数组大小的问题上有所不同@嗯,是的,我看过了。它说的第一件事是:“将数组的元素数更改为指定的新大小。”也许您的同事应该以不同的方式总结该方法。或者,您提到的差异主要是语义上的,除非您正在实现库或编译器。当列表大小增加时,列表是否做了大致相同的事情?如果我们关心性能,并且结构的大小变化很大,那么除了列表和数组之外,还有什么东西可以更好地为我们服务吗?@mcl:事实上,列表可以“调整”基础数组的大小(通过创建新数组和复制)。它使用双满策略实现,因此Add的摊销成本为O(1),但最坏情况下的成本为O(n),最坏情况下的内存损耗约为列表大小的100%。基本上,这个列表用浪费的内存来换取更快的速度。(我也同意,该页面的措辞还有很多需要改进的地方。这非常令人困惑。)鉴于MSDN声称“List类是ArrayList类的泛型等价物。它使用一个数组实现IList泛型接口,该数组的大小会根据需要动态增加。”这难道不意味着一旦编译,列表和数组的主要区别在于,列表中的一些方法需要检查是否需要调整大小?@mcl:基本上,每个访问都要经过一个包装层,而“原始”数组不会出现这种情况。这增加了一个小的性能影响。“每次添加一个项目”可能需要调整底层数组的大小,这并不完全正确;特别是,一行中从来没有很多这样的大小调整。List类经过精心设计,因此您永远不会遇到多个连续添加导致多个连续调整大小的情况。调整尺寸的摊销数量应与达到的最大尺寸的对数成比例;复制的项目总数应与最大大小成比例。@EricLippert:我知道;这就是为什么我把“可能”放在“可能需要”中。你可以肯定地看出,考虑到问题的严重性,避免使用“摊销”和“O(N)”等术语是有意的,目的是使答案简短且“足够接近”。你混淆了两个不同的东西。当完整列表是每个Add上的摊销O(1)操作时,增加double的大小。解决它;假设您从一个大小为1的数组开始,进行33次加法。你将在2点、3点、5点、9点、8点、17点16点和33点复制1个项目。调整大小的次数为O(logn);th