【问题标题】:Clear a collection or re-initialize?清除集合还是重新初始化?
【发布时间】:2012-05-05 02:02:00
【问题描述】:

我正在开发一个 .net 应用程序,我正在使用一个由 5 个列表和 1 个哈希表组成的对象。此对象在循环中使用,该循环至少迭代 500 次以运行某些分析。在每个循环中,这个对象应该开始为空,所以我想知道在所有列表和 Hashtable 上调用 clear 是否更有效,还是应该重新初始化该对象?

我知道我可以编写代码来对此进行基准测试,但我想知道是否有人已经走上了这条路?

谢谢。

【问题讨论】:

  • “我知道我可以编写代码来对此进行基准测试” - 你的情况和代码与其他人不同。做基准。我要补充一点,这似乎是一个微优化。您的代码实际上是否存在性能问题?
  • 这真的取决于你对对象和集合所做的事情。您甚至可以放置一个标志并说它是空的,然后覆盖内容而不清除。

标签: .net performance collections


【解决方案1】:

创建 3000 个空集合的成本将很小。除非你的“分析”真的很微不足道,否则这根本不会很重要。尽可能编写最清晰的代码——这很可能是每次都创建一组新的集合,而不是重复使用它们。如果 logical 操作要重用一个对象,您应该只重用它。

以最易读的方式编写代码后,请测试其性能是否符合您的需要。如果没有,那么您可以开始微优化。

但是,我强烈建议您使用Dictionary<,> 而不是Hashtable

【讨论】:

  • 即使在创建 100,000 个空集合的基准测试中,我也只能看到 00:00.001 的时间差异。首先是可读性。乔恩的回答很好。
【解决方案2】:

虽然我同意另一个答案,即这是一个微优化,但为了回答这个问题,我发现使用 List 时 new List 比 Clear 稍快。这是我的基准代码:

static void Main(string[] args)
    {
        var start = DateTime.Now;
        List<string> lst = new List<string>();

        for (int i = 0; i < 3000; ++i)
        {
            //lst = new List<string>();
            lst.Clear();
            for (int j = 0; j < 500; ++j)
            {
                lst.Add(j.ToString());
            }
        }

        Console.WriteLine("{0} ms", ((DateTime.Now - start).Ticks / TimeSpan.TicksPerMillisecond));
        Console.ReadLine();
    }

在五次运行中,新 List 平均为 340.8 毫秒,Clear 平均为 354.8 毫秒。

但是,这个结果非常接近,很明显:

  1. 差异可能毫无意义
  2. 我执行这个基准测试可能是在浪费时间

【讨论】:

  • 我认为您根本没有浪费时间。感谢您的努力。
  • 一,您正在为此使用 DateTime 类。更好地使用秒表以获得更高的准确性。第二,您正在测试代码中进行另一项主要操作(即List&lt;T&gt;.Add),这本身将花费大量时间给您几乎没有意义的值。三,new List&lt;string&gt;().Clear() 相比是一种不同的操作,后者保留了容量(以便以后的添加变得更快)。在前者的情况下,您可以通过以下方式实现相同的效果:new List&lt;T&gt;(lst.Capacity); +1 for benchmark still.
  • @nawfal 感谢 cmets 和 upvote!完全同意秒表的观点;现在我倾向于在 DateTime 上使用这个类,并且会敦促其他人也这样做。我也同意关于 lst.Add 的观点。事后看来,我应该在被基准测试的代码区域之外填充列表。虽然这会掩盖真实的结果,因为两个测试用例都使用相同的代码,但就最快的结果而言,结果应该仍然有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-29
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 2015-09-17
  • 2018-03-07
  • 1970-01-01
相关资源
最近更新 更多