【问题标题】:.net List<T> Trim Excess.net 列表<T> 修剪多余部分
【发布时间】:2012-07-15 09:34:05
【问题描述】:

考虑这种情况:Form1 构建了一个包含大量元素的 List 对象。然后,它必须通过参数将这个集合传递给 Form2。

我想在 Form2 中制作一个硬拷贝后清除与 Form1 中的集合相关的所有内容。让 Col1 成为 Form1 中集合的标识符。

由于 Col1 是通过参数通过引用传递的,我调用 Col1.Clear() 来清除它的元素,然后调用 Col1.TrimExcess() 到将其实际大小减小到 0,因此它不会跟踪大量 null 值。

我的目的是尽快清除所有使用过的内存。 Col1.TrimExcess() 应该清除所有使用的内存,但我很好奇 Col1 = null 在我(或大多数)情况下是否会更好?

【问题讨论】:

  • 我不明白为什么你想传递一个巨大的集合只是为了清除它“使用”的地方。请注意,传递引用并不意味着创建了副本。
  • 你能举个真实的例子吗?你的问题有点抽象。
  • 你可能想看看这个stackoverflow.com/questions/823661/…
  • Col1 = null 肯定比 Col1.Clear() + Col1.TrimExcess() 快(List(T).ClearList(T).TrimExcess 是 O(n) 操作)。
  • @Tim Schmelter - 你是对的。这就像建造一辆卡车来运输东西,但不是使用你刚刚建造的卡车,而是建造另一辆相同的卡车并摧毁第一辆。感谢您阐明我的逻辑缺陷 :) 现在我也在考虑放弃额外的表单并在第一个表单中使用标签。

标签: c# collections garbage-collection dynamic-memory-allocation


【解决方案1】:

我想调用 Col1.Clear() 来清除它的元素,然后调用 Col1.TrimExcess() 将是一个更好的方法,因为 Col1 = null 只会取消对列表的引用,但它仍然会在内存中,直到 GC 完成它的工作。

调用 Col1.Clear() 将从列表本身取消引用列表中的项目,然后 Col1.TrimExcess() 将从列表中删除所有空元素。

所以这样它会删除内存中所有内容的引用。

希望对你有帮助...

【讨论】:

  • 确实,你说的是真的。但是现在 Paolo 对我的问题发表了评论,我正在尝试权衡这两种解决方案:将列表设置为 null 是在恒定 (O(1)) 时间内完成的,但 GC 会花时间显示(多少是否会采取对我来说仍然未知,我必须做一些研究)。手动清除所有内容在 2 x O(n) 内完成,但无需等待 GC。
  • 手动清除列表不是 O(2n),因为对于 TrimExcess(),n 将为 0,因为您刚刚使用 Clear() 清除了它。但无论如何,我想依靠 GC 可以提供更好的性能,因为它已经完全优化过了。此外,它已融入运行时环境,因此它可能是用 C 或其他非常快的东西编写的。
【解决方案2】:

我猜你这样做是为了让你可以在 form1 中“准备”一些东西,然后将准备好的内容传递给 Form2 以避免某种滞后之类的东西,对吗?无论如何,有几个问题需要考虑:

正如 Tim Schmelter 所指出的,从表格 2 添加对列表“X”的引用不会创建副本 - 只会创建对 X 的新引用。从表格 2 中删除对 X 的引用也不应该减少内存,因为 X将仍然存在-只有一个指向它的指针会少一件事。但是,如果您确实创建了列表的硬拷贝,那么您确实可以通过删除对原始列表的所有引用及其包含的数据来节省一些内存。 (但请注意,deep copying a list is not always straight foreward...

至于使用clear()TrimExcess() 的天气,我通常认为这些是内置的,并期望它们表现得很好。无论如何,我非常怀疑它们是否会以任何显着方式影响您的代码速度。

另外,如果你应该选择使用col = null,你最终会得到一个具有空值的变量(显然......),而另一个选项最终会得到一个空(但非空)列表.如果我没记错的话,相当于“手动”将列表修剪为零长度不是将其设置为空,而是将其指向一个新的(空)列表:col = new List(),但我怀疑这会节省你任何 CPU 周期。

简而言之,我建议您像开始一样继续使用内置方法。

【讨论】:

  • 我正在通过 Col2.AddRange(Col1);我将集合传递给 Form2,因为 Form1 正在对初始数据运行过滤器,而 Form2 正在对先前过滤的数据运行第二个过滤器。但我认为这种界面碎片化是错误的,因为过滤器并没有那么无关紧要。我只会在一个表单上使用标签。我得到了我的答案,而你的答案是最具描述性的。我会接受它为有效的。
  • 很高兴能提供帮助(感谢您接受答案,我很感激)。
  • “无论如何,我非常怀疑它们会以任何显着方式影响您的代码速度。”这是不正确的。 Clear()TrimExcess() 都是 O(n) 操作,尽管后者的 n 为 0,因为列表为空。
【解决方案3】:

MSDN

要将列表重置为其初始状态,请在之前调用 Clear 方法 调用 TrimExcess 方法。修剪一个空列表设置 List 的容量为默认容量。

所以我猜你的方法是正确的。

【讨论】:

    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多