-3

我想知道什么更快。

list.Clear() or list = new List<..>()???

哪一个留下了很好的内存足迹?

引擎盖下会发生什么?

我知道这两个命令做两件不同的事情,因为第一个清除列表但不破坏实例,第二个释放旧实例但初始化新实例,尽管最终结果是相同的,那就是摆脱项目。

4

3 回答 3

9

以下List.Clear是实现方式(根据MSDN):

Count 设置为 0,并且从集合元素中对其他对象的引用也被释放。

容量保持不变。要重置列表的容量,请调用 TrimExcess 方法或直接设置容量属性。减小容量会重新分配内存并复制 List 中的所有元素。修剪空列表会将列表的容量设置为默认容量。

此方法是一个 O(n) 操作,其中 n 是 Count。

由于Clear是 O(n) 并且实例化一个新列表是 O(1),因此对于大型列表,重新实例化可能会更快(对于较短的列表,差异可能可以忽略不计)。

当然,由于(正如您已经知道的)它们的功能不同,您应该选择真正能满足您需求的那个。

于 2013-06-06T08:07:13.613 回答
2

操作员将new在托管堆中分配内存。如果list是前一个列表的唯一根,则该内存将在下一次 GC 期间回收(除非您明确调用GC.Collect,否则其执行实际上是不可预测的)。

内部List.Clear进行了调用Array.Clear,我猜只是将目标数组中的所有位设置为 0。这必须更快,但我不确定内存效率,因为它可能取决于特定情况(如果你有一个巨大的列表,你将只在new运算符之后部分使用它,我认为,它会更好只是释放旧内存并让列表的大小动态增长)。

于 2013-06-06T08:07:55.943 回答
2

创建新列表时要考虑的一件事是,在其他地方,也可能保留对列表的引用。如果您创建一个新列表,这些引用不会更改,代码将引用旧列表。

在这种情况下,使用清除列表Clear更安全,因为现在所有引用列表的位置都将使用清除的列表。

例子:

List<...> myGlobalList = new List<...>();
...

SomeWorkerClass wc = new SomeWorkerClass(myGlobalList);
myGlobalList = new List<...>();

wc仍将使用原始列表,而不是myGlobalList.

于 2013-06-06T08:10:46.177 回答