什么是 CLR 循环优化行为?

What is CLR loop optimization behavior?

我想知道如果我用 foreach 遍历一个数组,JITter 稍后会用简单的 for 循环替换 foreach 循环以减少枚举器惩罚,这是真的吗?如果是,那么 List 呢?因为列表由数组支持。

最后,Linq 的优化是什么,请考虑以下内容:

var result = typeof(List<int>).GetInterfaces()
    .FirstOrDefault(i => i.IsGenericType);

这会得到任何优化吗?

在 .NET 4.7.2650 上的 C# 2.8.2(应该是最新的 2018 年 7 月 25 日):

  • 数组上的forforeach已完全优化,

  • List<T> 上的 for 通过内联 .Count 和索引器 [] 的代码得到了完全优化。

您可以在 sharplab 上看到它,右窗格:方法 ArrayForArrayForEachListFor 不调用外部方法(但 ListFor 具有调用 ThrowArgumentOutOfRangeException 方法的代码,即由索引器 []) 进行的调用。 ListForEach 调用了 System.Collections.Generic.List``1+Enumerator[[System.Int32, mscorlib]].MoveNext() 所以它不是完全内联的。 EnumerableForEach 没有可以看到方法名称的显式调用,因为通过使用接口,它可以直接使用方法的地址(参见各种 call dword [0x218a0084]call dword [0x218a0088]...)

据我所知,

  • 你可以确定数组 上的 foreach 会被优化掉
  • Foreach List<T> 不会 被优化
  • 迭代 IEnumerable<T> 和 linq 不会 被优化

但是优化在很大程度上取决于编译器及其版本,因此最好的方法是使用编译器并在简单情况下检查 IL 代码。

Useful article from 2014