13

有人告诉我,以下代码块之间存在性能差异。

foreach (Entity e in entityList)
{
 ....
}

for (int i=0; i<entityList.Count; i++)
{
   Entity e = (Entity)entityList[i];
   ...
}

在哪里

List<Entity> entityList;

我不是 CLR 的期望,但据我所知,他们应该归结为基本相同的代码。是否有人以一种或另一种方式提供混凝土(见鬼,我会拿走泥土)证据?

4

7 回答 7

10

foreach 创建一个枚举器实例(从 GetEnumerator 返回),并且该枚举器还在 foreach 循环的整个过程中保持状态。然后它反复调用枚举器上的 Next() 对象,并为它返回的每个对象运行您的代码。

实际上,它们不会以任何方式归结为相同的代码,如果您编写自己的枚举器,您会看到这些代码。

于 2008-09-04T17:22:27.043 回答
9

是一篇很好的文章,展示了两个循环之间的 IL 差异。

Foreach 在技术上较慢,但更易于使用和阅读。除非性能很关键,否则我更喜欢 foreach 循环而不是 for 循环。

于 2008-09-04T17:24:50.580 回答
6

foreach 示例大致对应于这段代码:

using(IEnumerator<Entity> e = entityList.GetEnumerator()) {
    while(e.MoveNext()) {
        Entity entity = e.Current;
        ...
    }
}

这里有两个成本是常规 for 循环不需要支付的:

  1. 通过 entityList.GetEnumerator() 分配枚举器对象的成本。
  2. 列表中每个元素的两个虚拟方法调用(MoveNext 和 Current)的成本。
于 2008-09-04T17:32:22.763 回答
3

这里遗漏了一点:List 有一个 Count 属性,它在内部跟踪其中有多少元素。

一个 IEnumerable 没有。

如果您对接口 IEnumerable 进行编程并使用计数扩展方法,它将仅枚举元素以计数。

尽管在 IEnumerable 中您不能按索引引用项目,但这是一个有争议的问题。

因此,如果您想锁定列表和数组,您可以获得小的性能提升。

如果您想要灵活性,请使用 foreach 并将程序设置为 IEnumerable。(允许使用 linq 和/或 yield return)。

于 2008-09-04T17:56:26.947 回答
1

在分配方面,最好看看这篇博文。它准确显示了在什么情况下在堆上分配了枚举数。

于 2008-09-04T17:36:10.710 回答
0

我认为您可能会获得性能提升的一种可能情况是可枚举类型的大小和循环条件是否为常数;例如:

const int ArraySize = 10;
int[] values = new int[ArraySize];

//...

for (int i = 0; i 

In this case, depending on the complexity of the loop body, the compiler might be able to replace the loop with inline calls. I have no idea if the .NET compiler does this, and it's of limited utility if the size of the enumerable type is dynamic.

One situation where foreach might perform better is with data structures like a linked list where random access means traversing the list; the enumerator used by foreach will probably iterate one item at a time, making each access O(1) and the full loop O(n), but calling the indexer means starting at the head and finding the item at the right index; O(N) each loop for O(n^2).

Personally I don't usually worry about it and use foreach any time I need all items and don't care about the index of the item. If I'm not working with all of the items or I really need to know the index, I use for. 唯一一次我认为这是一个大问题是链表之类的结构。

于 2008-09-04T17:31:02.453 回答
0
For Loop
for loop is used to perform the opreration n times
for(int i=0;i<n;i++)
{
l=i;
}
foreach loop

int[] i={1,2,3,4,5,6}
foreach loop is used to perform each operation value/object in IEnumarable 
foreach(var k in i)
{
l=k;
}
于 2014-01-13T06:14:27.873 回答