.net 列表<;T>;或LinkedList<;T>;

.net 列表<;T>;或LinkedList<;T>;,.net,algorithm,data-structures,collections,.net,Algorithm,Data Structures,Collections,我需要一个包含相同类型元素列表的数据结构。所需功能包括 加 GetEnumerator (可能)清楚 不需要索引访问、排序、搜索和删除元素。什么是最好的收藏类?应该考虑以下方面:性能、内存使用、垃圾收集器的行为 我目前的候选者是List和LinkedList,除非你正在处理一个庞大的结构,或者你计划对这个东西进行万亿次的迭代,否则这并不重要。只需选择一个,然后开始编码。如果你的应用程序后来慢到爬行,请找出原因,并根据需要进行更改 (说真的,这不重要。一点也不重要。你花在找到这个问题答案上的每

我需要一个包含相同类型元素列表的数据结构。所需功能包括

  • GetEnumerator
  • (可能)清楚
不需要索引访问、排序、搜索和删除元素。什么是最好的收藏类?应该考虑以下方面:性能、内存使用、垃圾收集器的行为


我目前的候选者是
List
LinkedList

,除非你正在处理一个庞大的结构,或者你计划对这个东西进行万亿次的迭代,否则这并不重要。只需选择一个,然后开始编码。如果你的应用程序后来慢到爬行,请找出原因,并根据需要进行更改

(说真的,这不重要。一点也不重要。你花在找到这个问题答案上的每一分钟都离你有工作代码的时间近了一分钟)


如果任何人都需要知道它们之间的区别,LinkedList比List更快,并且可以在您只需要非随机、仅向前读取和附加功能时使用。

如果不需要索引访问,您最好使用
LinkedList
。没有太大区别,但是LinkedList可以更快地用于附录。

我会使用
List
,因为如果所有数据都是值类型,并且与引用类型的关系仍然很好,那么所有数据都会按顺序存储(在内部,
List
管理一个数组,该数组在每次空间用完时都会增长两倍)

LinkedList
过去在不受IO限制的情况下更有意义。人们经常会引用它表面上的“O(1)”性质。但是,这降低了页面错误获取节点的机会增加所带来的实际成本

如果您可以使用数组或
列表获得连续的内存区域,并避免潜在的页面错误,那么使用现代处理器和主内存缓存线会更好

如果您事先知道将有多少个元素,请使用数组。如果您知道有多少个元素,请使用
列表
(并在构造函数中传递可能的上限以避免重新分配)

我唯一一次使用
LinkedList
是如果您需要不断地将列表中的项目按一个值递增。例如,如果您正在实现一个缓存算法,并且需要在前端添加一些内容,并从后端删除一些内容

对于小项目,这真的不会有什么区别。分代垃圾收集器将随着时间的推移将分散的堆项目压缩在一起,这样链表就不会变得太糟糕


我会选择一个
列表
并运行它,除非您注意到问题(通过分析)

除非您正在处理数十万或数百万条条目,并且您已经分析了您的程序以发现存在重大问题,您可能不会注意到两者之间的区别

除此之外:

LinkedList
提供了类型为
LinkedListNode
的独立节点,因此插入和删除是O(1)操作


从。

链接列表将带来更多的内存开销(对于节点),但如果在中间插入许多元素则更好。链表也需要更多的内存分配,因为LinkedListNode是一个类,是动态分配的。如果不插入元素(只是追加),我将使用列表。添加列表的速度应该与添加列表的速度一样快或更快,尽管有时需要放大列表

如果你的阵列足够大,你需要自己滚动。。。否则,只需使用列表。

鉴于您对接口的需求,您应该在代码中的任何地方使用
ICollection
,而不是引用特定的具体类

原因是,如果使用
List
,则可以编写一组代码,使用
l[0]
获取第一项。另一方面,如果使用
LinkedList
,则可能会在整个代码中分散对
AddLast
的调用。为了保留切换的选择,您需要避免意外地依赖于您并不真正需要的功能。您需要使用两个容器都支持的接口

所以写一个这样的类:

public static class Collections
{
    public static ICollection<T> Make<T>()
    {
        return new List<T>();
    }
}
公共静态类集合
{
公共静态ICollection Make()
{
返回新列表();
}
}
然后,无论何时需要收藏,请执行以下操作:

ICollection<int> c = Collections.Make<int>();
ICollection c=Collections.Make();
将您选择的容器与程序的其余部分隔离开来。现在,当您分析并改变想法时,您只需编辑
Make
方法。

简短回答
几乎在所有情况下都默认使用
List

回答稍微长一点
LinkedList
只有在添加和删除大量值的情况下才会比枚举这些值更好,而且列表的大小很大。只有在分析后发现使用
List
存在问题时,这才应该是您选择的一个因素

更长的答案

假设,您已经将其中一个的使用确定为性能问题

如果你做了大量的随机访问,那么无论发生什么情况,
List
几乎总是会大大加快速度。 如果你列举了很多并且很少插入(或者几乎总是在末尾插入),那么
列表几乎总是会更快。
如果您经常在随机位置插入/删除,但在迭代列表时,这些元素已经位于或接近相关节点,并且至少有数千个元素,您可能希望尝试
LinkedList

确定哪些价值/用途转化为更好的性能在很大程度上取决于您的使用情况。微基准在这里可能会产生误导,因为