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