一组相关数据,如零件清单等,可以使用Arrays(Array of Parts)或使用Collection进行处理。我了解当使用Arrays时,Insertion,Deletion和其他一些操作在与Collections进行比较时会对性能产生影响。这是否意味着集合内部不使用数组?如果是,那么用于List,Collection等集合的数据结构是什么?
如何在内部处理馆藏?
答案 0 :(得分:4)
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>
。
答案 1 :(得分:1)
实现简单集合有两种基本方法:
连续数组对于您提到的操作具有性能缺点,因为集合的内存空间要么预先分配,要么根据集合的内容进行分配。因此,删除或插入需要移动许多数组元素,以使整个集合保持连续且顺序正确。
链接列表会删除这些问题,因为集合中的项目不需要连续存储在内存中。相反,每个元素都包含对一个或多个其他元素的引用。因此,当进行插入时,所讨论的项目将在内存中的任何位置创建,并且只需要修改集合中已有的一个或两个元素的引用。
例如:
LinkedList<object> c = new LinkedList<object>(); // a linked list
object[] a = new object[] { }; // a contiguous array
当然这是简化的。 LinkedList<>
的内部无疑比简单的单链或双链表更复杂,但这是基本结构。
答案 2 :(得分:-1)
我认为某些集合类可能在内部使用数组以及链接列表或类似的东西。使用System.Collections命名空间而不是数组的集合的好处是,您不需要花费额外的时间编写代码来执行更新操作。
阵列总是更轻量级,如果你知道一些非常好的搜索算法,那么你甚至可以更有效地使用它们,但大多数时候你可以通过使用System中的类来避免重新发明轮子。集合。这些类旨在帮助程序员避免编写已经编写和调试数百次的代码,因此不太可能通过自己操作数组来获得显着的性能提升。
如果您需要一个不需要添加,删除或编辑的静态集合,那么也许现在是使用数组的好时机,因为它们不需要集合所需的额外内存。