【问题标题】:.NET Collection Classes.NET 集合类
【发布时间】:2011-05-15 10:42:42
【问题描述】:

相关数据组,如部件列表等,可以使用数组(部件数组)或使用集合来处理。我了解当使用数组时,插入、删除和其他一些操作在与集合进行比较时会对性能产生影响。这是否意味着集合内部不使用数组?如果是这样,List、Collection 等集合使用的数据结构是什么?

内部如何处理集合?

【问题讨论】:

  • 你说的是Collection还是Collection<T>?因为装箱/拆箱是一个重要的考虑因素/性能影响(通过通用集合解决)
  • 我正在讨论使用的内部数据结构,您可以考虑使用 Collection 或 Collection。以 Collection. 为例
  • 顺便说一句,请注意没有 C# 集合类。它们都是 .NET 集合类,可以在任何 .NET 语言中使用。
  • 约翰我同意你的看法。添加 C# 作为标题的一部分是一个错误。感谢您纠正错误。拉姆

标签: c# .net collections


【解决方案1】:

List<T> 使用内部数组。在列表开头附近删除/插入项目将比在列表末尾附近执行相同操作更昂贵,因为内部数组的全部内容需要向一个方向移动。此外,一旦您尝试在内部列表已满时添加项目,则会构造一个新的更大的数组,复制内容并丢弃旧数组。

Collection<T> 类在与无参数构造函数一起使用时,在内部使用 List<T>。所以在性能方面它们将是相同的,除了包装引起的开销。 (本质上是多了一层间接性,在大多数情况下可以忽略不计。)

LinkedList<T>,顾名思义,是一个链表。这将牺牲插入/移除速度的迭代速度。由于迭代意味着无限地遍历指针到指针的指针,因此总体上这将需要更多的工作。除了指针遍历之外,两个节点可能不会分配到彼此靠近的任何地方,从而降低了 CPU RAM 缓存的效率。

但是,插入或删除节点所需的时间量是恒定的,因为无论列表的状态如何,它都需要相同数量的操作。 (这不考虑实际定位要删除的项目或遍历列表以找到插入点所必须完成的任何工作!)

如果您对收藏的主要关注是测试收藏中是否有某些东西,您可以考虑使用HashSet<T>。将项目添加到集合中会相对较快,介于插入列表和链接列表之间。物品的移除将再次相对较快。但真正的收获在于查找时间——测试HashSet<T> 是否包含一个项目不需要迭代整个列表。平均而言,它的执行速度比任何列表或链表结构都快。

但是,HashSet<T> 不能包含等效项。如果您的部分要求是被认为相等的两个项目(通过Object.Equals(Object) 重载,或通过实现IEquatable<T>)在集合中独立共存,那么您根本不能使用HashSet<T>。此外,HashSet<T> 不保证插入顺序,因此如果维护某种顺序很重要,您也不能使用 HashSet<T>

【讨论】:

  • 您好 cdhowie,感谢您的回答。你有任何网址可以参考阅读有关此主题的内容吗? - 公羊
  • 是的,this awesome website 有一些很好的信息。 ;)
【解决方案2】:

实现简单集合有两种基本方法:

  • 连续数组
  • 链表

对于您提到的操作,连续数组具有性能劣势,因为集合的内存空间是根据集合的内容预先分配或分配的。因此删除或插入需要移动许多数组元素以保持整个集合的连续性和正确的顺序。

链接列表消除了这些问题,因为集合中的项目不需要连续存储在内存中。相反,每个元素都包含对一个或多个其他元素的引用。因此,当进行插入时,相关项会在内存中的任何位置创建,并且只需要修改对集合中已经存在的一两个元素的引用。

例如:

LinkedList<object> c = new LinkedList<object>(); // a linked list
object[] a = new object[] { }; // a contiguous array

这当然是简化的。 LinkedList&lt;&gt; 的内部结构无疑比简单的单链表或双链表更复杂,但这是基本结构。

【讨论】:

  • 您好 Joel Potter,感谢您的回答,这是有道理的。如果你有的话,你能提供一些参考资料(讨论这个话题的链接) - Ram
【解决方案3】:

我认为某些集合类可能在内部使用数组以及链表或类似的东西。使用 System.Collections 命名空间中的集合而不是数组的好处是您无需花费任何额外的时间编写代码来执行更新操作。

数组总是更轻量级,如果你知道一些非常好的搜索算法,那么你甚至可以更有效地使用它们,但大多数时候你可以通过使用 System.收藏品。这些类旨在帮助程序员避免编写已经编写和调整过数百次的代码,因此您不太可能通过自己操作数组来获得显着的性能提升。

当您需要一个不需要太多添加、删除或编辑的静态集合时,也许是使用数组的好时机,因为它们不需要集合所需的额外内存。

【讨论】:

  • 在阅读了 cdhowie 发布的内容后,我意识到我忘记提及您选择哪个收藏确实会有所不同。根据您最常执行的操作选择它们。
猜你喜欢
  • 2010-10-30
  • 2010-10-25
  • 2010-09-16
  • 2011-04-13
  • 1970-01-01
  • 2023-03-28
  • 2016-04-12
  • 1970-01-01
  • 2016-02-13
相关资源
最近更新 更多