C# 关于枚举空列表的性能问题

C# 关于枚举空列表的性能问题,c#,C#,当您可能有一个空列表时,性能方面哪一个更好 if (_myList != null && _myList.Count > 0) { foreach (thing t in _myList ) { ... 或者不检查我的列表计数是否包含任何内容: if (_myList != null) { foreach (thing t in _myList ) { ... 我猜可能没有多少,但第一个稍微快一点(?) 谢谢 编辑: 澄清一下,我指的是这

当您可能有一个空列表时,性能方面哪一个更好

if (_myList != null && _myList.Count > 0)
{
  foreach (thing t in _myList )
  {
    ...
或者不检查我的列表计数是否包含任何内容:

if (_myList != null)
{
  foreach (thing t in _myList )
  {
   ...
我猜可能没有多少,但第一个稍微快一点(?)

谢谢


编辑:


澄清一下,我指的是这样的列表:
list

除非您在一个紧密的循环中调用代码,否则差异将是微不足道的。但是,请注意有一个区别:检查
\u myList.Count>0
可以避免调用
GetEnumerator
、创建IEnumerator实现对象(堆分配)和调用该枚举器的
MoveNext()
方法


如果您在避免的性能方面处于紧张状态(堆分配+虚拟方法调用),可能会有所帮助,但通常情况下,通过避免显式打开
\myList.Count

,您的代码会更短,更容易理解,除非您是在一个紧张的循环中调用代码,否则差异将是微不足道的。但是,请注意有一个区别:检查
\u myList.Count>0
可以避免调用
GetEnumerator
、创建IEnumerator实现对象(堆分配)和调用该枚举器的
MoveNext()
方法


如果您在性能方面处于困境,避免(堆分配+虚拟方法调用)可能会有所帮助,但通常情况下,通过避免在
\myList.Count上显式显示,您的代码会更短,更容易理解。只有一种方法可以回答性能问题:

  • 测量
  • 测量
  • 测量
  • 只有这样,您才能知道:

    • 我可以改进代码
    • 我已经改进了代码
    • 最重要的是:首先要改进哪些代码
    是测量程序的不同部分花费了多少时间,然后首先改进最重要的项目

    为了回答您的问题,我假设,与仅仅调用Count(假设这是一个快速调用,例如字段读取)相比,几个额外对象的微小开销确实会花费您一些周期

    然而,既然你问了这个问题,它告诉我你没有足够的关于你的程序和代码状态的信息,所以改善这个微小的开销对你的用户产生显著影响的机会是如此渺茫,我不想费心了

    我可以保证,从性能上看,你还有更重要的事情要做,所以先解决这些问题


    就个人而言,我不使用
    null
    引用,除非在处理数据库时或在几行代码中表示“尚未初始化”,除此之外,我使用空列表和字符串等。您的代码更易于阅读和理解,在这一层面上,微优化的好处永远不会被注意到。

    只有一种方法可以回答性能问题:

  • 测量
  • 测量
  • 测量
  • 只有这样,您才能知道:

    • 我可以改进代码
    • 我已经改进了代码
    • 最重要的是:首先要改进哪些代码
    是测量程序的不同部分花费了多少时间,然后首先改进最重要的项目

    为了回答您的问题,我假设,与仅仅调用Count(假设这是一个快速调用,例如字段读取)相比,几个额外对象的微小开销确实会花费您一些周期

    然而,既然你问了这个问题,它告诉我你没有足够的关于你的程序和代码状态的信息,所以改善这个微小的开销对你的用户产生显著影响的机会是如此渺茫,我不想费心了

    我可以保证,从性能上看,你还有更重要的事情要做,所以先解决这些问题


    就个人而言,我不使用
    null
    引用,除非在处理数据库时或在几行代码中表示“尚未初始化”,除此之外,我使用空列表和字符串等。您的代码更易于阅读和理解,在这一层面上,微优化的好处永远不会被注意到。

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

    尽管如此,Count对于System.Generics.Collection.List几乎肯定会更快

    尽管优化大大改善了情况(不要害怕使用
    foreach
    !它几乎是免费的),
    foreach
    或多或少涉及到:

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

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

    强制性免责声明:在尝试“优化它”之前,您应该已经通过分析确定这是一个问题区域,因此,您手头已经有了一套工具,可以快速轻松地确定哪些方法更快。很可能,两者都不会对应用程序的性能产生明显的影响

    尽管如此,Count对于System.Generics.Collection.List几乎肯定会更快

    尽管优化大大改善了情况(不要害怕使用
    foreach
    !它几乎是免费的),
    foreach
    或多或少涉及到:

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

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

    我敢打赌,当列表为空时,性能并不重要。