【问题标题】:Does F# compiler support foreach optimization in the same way as C# compiler doesF# 编译器是否以与 C# 编译器相同的方式支持 foreach 优化
【发布时间】:2016-04-18 22:50:40
【问题描述】:

This is a detailed answer 关于在 IEnumerator<T> 是可变结构的情况下 C# 编译器如何优化 foreach

F# 编译器是否执行相同的优化?

【问题讨论】:

    标签: .net f#


    【解决方案1】:

    AFAICT 似乎 F# 对待 valuetype 枚举器的方式与 C# 类似:

    这里是一个简单的 C# 程序的 IL 代码的反汇编 sn-p,该程序在 IEnumerable<T> 上使用 foreach

    .locals init (
        [0] valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>,
        [1] int32 v
    )
    IL_0025: ldloca.s 0
    IL_0027: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::MoveNext()
    

    注意local 0 是一个值类型,它使用ldloca.s 来加载结构的地址。

    与 F# 比较

    .locals init (
        [0] class [mscorlib]System.Collections.Generic.List`1<int32> ra,
        [1] valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>
    )
    IL_000e: ldloca.s 1
    IL_0010: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::MoveNext()
    

    此代码还使用 valuetype 声明 local 1ldloca.s 以加载结构的地址。

    附带说明:后来的 F# 版本实际上做了 C# 不做的优化。因为在 F# 中迭代​​作为不可变数据结构的 F# 列表是一种常见模式,所以使用枚举器进行迭代是无效的。所以 F# 对列表有一个特殊情况,并在这种情况下应用更有效的算法。在 C# 中迭代​​ F# 列表将回退到枚举器。

    也可以对IList 类型实现特殊处理,但由于可能有人以“有趣”的方式实现了IList,因此实现这种优化可能是一个突破性的变化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      • 1970-01-01
      相关资源
      最近更新 更多