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

本文关键字:列表 性能 问题 于枚举 枚举 | 更新日期: 2023-09-27 17:49:27

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

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

或者不检查_myList count是否包含任何内容:

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

我猜可能没有太多内容,但是第一个稍微快一点(?)

感谢
编辑:

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

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

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

你唯一能知道的方法是:

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

是衡量程序的不同部分所花费的时间,然后首先改进最重要的项目。

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

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

我可以保证你有更重要的事情要做,所以先解决这些问题。

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

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

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

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

但话虽如此,Count for system . generic . collection . list <>几乎肯定会更快。

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

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

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