【问题标题】:Should I check the Count of the collection before using foreach?我应该在使用 foreach 之前检查集合的计数吗?
【发布时间】:2014-10-13 11:12:59
【问题描述】:

在使用 foreach 枚举内容之前添加对集合计数的检查是否会提高性能?

if (users.Count != 0) {
  foreach (var user in users) {
     // do what snowmen do in summer
  }
}

对比

 foreach (var user in users) {
     // do what snowmen do in summer
  }

我的函数花费的时间有点太长,所以我想知道这是否会稍微提高性能,以将我的函数执行时间缩短到我需要的地方。

编辑(执行此循环的上下文):

for (DateTime day = dayStart; day < dayEnd; day = day.addMinutes(30)) {
  // Other actions
  if (users.Count != 0) {
    foreach (var user in users) {
       // do what snowmen do in summer
    }
  }
}

【问题讨论】:

  • 这就是所谓的过早优化。您应该使用if(users.Any())if(users.Count != 0) 的唯一原因是您要处理没有用户的情况。
  • 你试过了吗?不过可能没有任何区别。
  • 否;这不是一个改进:优化器可以自己做这么简单的把戏。如果您希望更快地实现,请仔细检查代码 within foreach 循环。
  • 你必须测量,这很大程度上取决于处理器预测分支的可能性。错误预测的分支非常昂贵。 this post 覆盖得很好。
  • 在现代处理器上,for and for-each loops compile to roughly an if-statement wrapped around a do-while。该隐式 if 语句精确地检查零。因此,如果编译器不删除它,包装另一个(冗余)if 语句实际上可能是 悲观

标签: c# if-statement optimization foreach


【解决方案1】:

这两个脚本的结果是一样的。

如果计数为零,Foreach 将不做任何事情,因此不需要 if 语句。

在纳秒和更大的执行差异并没有更快,如果列表有项目,它会变慢,但在这两种情况下你不会注意到任何东西。

【讨论】:

  • 我知道结果是一样的,我想知道“if”是否比 foreach(var x (where x.count = 0) in y) 快?
  • 严格来说这不一样,因为if 阻止了GetEnumerator 需要被执行。但是使用if 可能很重要的唯一原因是您要处理else 中没有用户的情况。
  • 两者的结果相同但执行不同。不,纳秒或更多的差异不会更快,如果列表有项目,它会更慢,但在这两种情况下你不会注意到任何东西。
  • 是的@oussamaabdou,这就是我正在寻找的答案,你能把它制定出来,然后我会给你信用。
【解决方案2】:

第一个版本可能是降级了。

foreach 中的第一条指令很有可能是对空虚的快速测试。所以你基本上重复了两次。

无论如何,这种“纳米优化”在实践中没有明显的效果。

(除非在大多数情况下,Count 为零。)

【讨论】:

  • 即使Count 在所有情况下都为零,我怀疑明确的If-then-else 陷阱会比立即终止的ForEach 循环更有效。
  • 不确定,这取决于users对象的类型;在退出测试之前可能会有一些初始化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-13
  • 2015-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多