C# &引用;foreach“;VS";列表<;T>;。Foreach“;。。。哪个赢

C# &引用;foreach“;VS";列表<;T>;。Foreach“;。。。哪个赢,c#,performance,generics,compiler-construction,foreach,C#,Performance,Generics,Compiler Construction,Foreach,在性能级别上,哪一个更倾向于使用,哪一个在编译器工作方面更轻,有什么主要区别吗 List<int> intList; foreach (int i in intList) TL;DR:这里的性能差异在实际应用中几乎可以肯定是微不足道的,而且还有一种更具可读性的方法来实现相同的结果。不过,看到编译代码中的差异仍然很有趣 假设完整代码实际上是: int result = 0; foreach (int i in intList) { result += i; } vs

在性能级别上,哪一个更倾向于使用,哪一个在编译器工作方面更轻,有什么主要区别吗

  List<int> intList;
  foreach (int i in intList)

TL;DR:这里的性能差异在实际应用中几乎可以肯定是微不足道的,而且还有一种更具可读性的方法来实现相同的结果。不过,看到编译代码中的差异仍然很有趣

假设完整代码实际上是:

int result = 0;
foreach (int i in intList)
{
    result += i;
}
vs

然后,就生成的内容而言,第一种形式相当简单-最终只需要一个局部变量、在列表上迭代的代码(使用
list.Enumerator
)和将值添加到局部变量的IL

第二种形式需要生成一个新类,其中包含
result
的实例变量,以及要用作委托的方法。代码将转换为:

CompilerGeneratedClass tmp = new CompilerGeneratedClass();
tmp.result = 0;
Action<int> tmpDelegate = new Action<int>(tmp.CompilerGeneratedMethod);
intList.ForEach(tmpDelegate);

我怀疑性能差异实际上会成为实际代码中的瓶颈,但LINQ版本是IMO中最清晰的版本,这始终是一件好事。

您可以这样衡量每个版本所花费的时间:

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
“您的代码在这里”


当你测量它时,你的结果是什么?你试过检查自己吗?你知道如何测试代码的性能吗?可能重复的可能重复的
CompilerGeneratedClass tmp = new CompilerGeneratedClass();
tmp.result = 0;
Action<int> tmpDelegate = new Action<int>(tmp.CompilerGeneratedMethod);
intList.ForEach(tmpDelegate);
int result = intList.Sum();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
stopWatch.Stop();
Console.WriteLine(stopWatch.Elapsed.ToString());