【问题标题】:Implementation of List<T> in C#?C# 中 List<T> 的实现?
【发布时间】:2013-07-28 02:55:30
【问题描述】:

首先我很抱歉我的英语不好,然后是我的问题;

我知道有很多这样的问题,在这里,但我没有找到一个直接的答案。 List&lt;T&gt; 是否使用某种“链表”机制实现?还是只是一个过度设计的数组?

我对列表的性能问题感兴趣,例如排序、插入和删除项目。例如。对于插入操作,“链表”只是定义了一些新的连接,但数组需要改变它的值。清单呢?

【问题讨论】:

  • 这是一个数组。在 F# 中,它们使用名称 ResizeArray&lt;'T&gt; 来表示相同的 List`1[T] 类型。
  • List&lt;T&gt;的源代码;搜索“Microsoft shared source Initiative”,你会找到它。然后你可以自己回答这样的问题。 (回答您的问题:List&lt;T&gt; 被实现为一个数组;当数组已满时,将分配一个大小为原来的两倍的新数组并从旧数组中填充。)

标签: c# list implementation


【解决方案1】:

是的,List 是一个数组。是的,Insert() 是一个 O(n) 操作。

以这种方式工作很重要,现代处理器非常依赖于它们的缓存。您机器中的 RAM 非常慢,比处理器慢得多。高速缓存可以快速顺序访问内存。这与 LinkedList 的作用相反。单个缓存未命中会花费数百个 cpu 周期。请注意 LinkedList 的另一个显着缺点,除非您可以按顺序索引,否则索引它的成本为 O(n)。 List 总是 O(1)。

这些只是粗略的指导方针,没有人可以建议您将列表替换为 LinkedList。只有分析器才能做到这一点。

【讨论】:

  • 谢谢汉斯,你是对的。我会坚持我的 List,因为我的数组大小不会超过 5000-10000。
  • 我还设置了一个小测试,将一个值“插入”到列表和数组中(n=100M)。在一次运行中,array 稍微快一些,但在一个有 25 个循环的循环中,list 以显着差异赢得了平均运行时间。当我将n增加到110M时,列表在我的机器上抛出了溢出异常,但数组没有。
【解决方案2】:

我会说它只是一个过度设计的数组。对于链接列表,您需要LinkedList&lt;T&gt;。有关LinkedList&lt;T&gt; 的更多信息,请阅读this

【讨论】:

    【解决方案3】:

    我认为List&lt;T&gt; 是一个过度设计的数组,而不是一个“链表”。

    至于性能,由于List&lt;T&gt;本身没有排序,所以性能取决于排序算法(冒泡排序非常慢,因为每个项目都需要检查)。

    List&lt;T&gt; 中插入和删除项目非常简单,使用List&lt;T&gt;.Add()List&lt;T&gt;.Insert() 可以提高插入项目的性能,因为.Add() 会将其添加到列表的末尾。

    要全面了解各种 .NET 集合类型的性能和一般用例,请阅读C#/.NET Fundamentals: Choosing the Right Collection Class

    【讨论】:

    • 您提供的链接很棒!
    • 感谢卡尔的链接。这真的很有帮助。
    【解决方案4】:

    不,List 不是链表,它只是一个方便的强类型数组。我不会把它称为工程数组,但它是从 C# 2.0 引入的最佳特性之一。如果使用通用列表的性能是一个问题,则可以根据用例对其进行优化,但即使在巨大的列表中插入也不会花费太多时间。

    【讨论】:

      猜你喜欢
      • 2011-10-09
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 1970-01-01
      • 2013-10-06
      相关资源
      最近更新 更多