有关枚举空列表的性能问题

时间:2011-04-06 10:23:02

标签: c#

当你可能有一个空列表时,哪个更好,性能更好?

if (_myList != null && _myList.Count > 0)
{
  foreach (thing t in _myList )
  {
    ...

或不检查_myList计数是否包含任何内容:

if (_myList != null)
{
  foreach (thing t in _myList )
  {
   ...

我猜它可能不多,但第一个是稍微更快(?)

由于


编辑:

澄清一下,我的意思是这样一个列表:List<Thing>

3 个答案:

答案 0 :(得分:3)

只有一种方法可以回答效果问题:

  1. 测量
  2. 测量
  3. 测量
  4. 唯一可以知道的方法是:

    • 我可以改进代码
    • 改进了代码
    • 最重要的是:首先改进哪些代码

    用于衡量程序的不同部分所花费的时间,然后首先改进顶部项目。

    要回答你的问题,我会假设一些额外对象的微不足道的开销确实会花费你一些周期而不是只调用Count(假设这是一个快速调用,例如字段读取)。

    然而,既然你问这个问题它会告诉我你没有足够的关于你的程序状态和你的代码的信息,所以改善这个微不足道的开销实际上对你的用户产生显着影响的机会是如此苗条,我不会打扰。

    我可以保证你有更大的鱼来锻炼性能,所以先解决这些问题。

    我个人不会使用null引用,除非在处理数据库时或在几行代码中发出“尚未初始化”的信号,除此之外我还使用空列表和字符串等。您的代码是更容易阅读和理解,并且永远不会注意到微观优化在这个层面上的好处。

答案 1 :(得分:1)

除非您在紧密循环中调用代码,否则差异无关紧要。但是,请注意存在差异:检查_myList.Count > 0会避免调用GetEnumerator,创建IEnumerator实现对象(堆分配)以及调用该枚举器的MoveNext() } 方法。

如果你处于紧张的性能状态,避免(堆分配+虚拟方法调用)可能有所帮助,但一般来说,通过避免显式_myList.Count,您的代码更短,更容易理解。

答案 2 :(得分:1)

强制免责声明:在尝试“优化”之前,您应该已经通过性能分析将此识别为问题区域,因此您已经拥有了一些工具,可以更快速,更轻松地快速确定哪些方法。可能性,也不会对您的应用程序的性能产生明显的影响。

但是,据说,Count,System.Generics.Collection.List&lt;&gt;几乎肯定会更快。

虽然优化改善了极大(不要害怕使用foreach!它几乎是免费的),foreach或多或少涉及:

var enumerator = _myList.GetEnumerator();
try
{
  while (enumerator.MoveNext())
  {
  }
}
finally
{
  enumerator.Dispose();
}

这比仅仅比较一个简单属性(List.Count是一个简单属性的安全假设)和常量要复杂得多。