我想知道什么更快。
list.Clear() or list = new List<..>()???
哪一个留下了很好的内存足迹?
引擎盖下会发生什么?
我知道这两个命令做两件不同的事情,因为第一个清除列表但不破坏实例,第二个释放旧实例但初始化新实例,尽管最终结果是相同的,那就是摆脱项目。
我想知道什么更快。
list.Clear() or list = new List<..>()???
哪一个留下了很好的内存足迹?
引擎盖下会发生什么?
我知道这两个命令做两件不同的事情,因为第一个清除列表但不破坏实例,第二个释放旧实例但初始化新实例,尽管最终结果是相同的,那就是摆脱项目。
以下List.Clear
是实现方式(根据MSDN):
Count 设置为 0,并且从集合元素中对其他对象的引用也被释放。
容量保持不变。要重置列表的容量,请调用 TrimExcess 方法或直接设置容量属性。减小容量会重新分配内存并复制 List 中的所有元素。修剪空列表会将列表的容量设置为默认容量。
此方法是一个 O(n) 操作,其中 n 是 Count。
由于Clear
是 O(n) 并且实例化一个新列表是 O(1),因此对于大型列表,重新实例化可能会更快(对于较短的列表,差异可能可以忽略不计)。
当然,由于(正如您已经知道的)它们的功能不同,您应该选择真正能满足您需求的那个。
操作员将new
在托管堆中分配内存。如果list
是前一个列表的唯一根,则该内存将在下一次 GC 期间回收(除非您明确调用GC.Collect
,否则其执行实际上是不可预测的)。
内部List.Clear
进行了调用Array.Clear
,我猜只是将目标数组中的所有位设置为 0。这必须更快,但我不确定内存效率,因为它可能取决于特定情况(如果你有一个巨大的列表,你将只在new
运算符之后部分使用它,我认为,它会更好只是释放旧内存并让列表的大小动态增长)。
创建新列表时要考虑的一件事是,在其他地方,也可能保留对列表的引用。如果您创建一个新列表,这些引用不会更改,代码将引用旧列表。
在这种情况下,使用清除列表Clear
更安全,因为现在所有引用列表的位置都将使用清除的列表。
例子:
List<...> myGlobalList = new List<...>();
...
SomeWorkerClass wc = new SomeWorkerClass(myGlobalList);
myGlobalList = new List<...>();
wc
仍将使用原始列表,而不是myGlobalList
.