F#自动内联某些函数,即使它们没有标记为“inline”,这是有意的吗?
看起来F#会自动内联一些函数,即使它们没有标记为“inline” 通过检查IL,我看到编译器已经积极地内联了F#自动内联某些函数,即使它们没有标记为“inline”,这是有意的吗?,f#,inline,F#,Inline,看起来F#会自动内联一些函数,即使它们没有标记为“inline” 通过检查IL,我看到编译器已经积极地内联了funB&a,b funC: IL_0000: nop IL_0001: ldarg.0 IL_0002: ldc.i4.3 IL_0003: add IL_0004: stloc.0 // s IL_0005: ldarg.0 IL_0006: ldarg.0 IL_0007: mul
funB
&a,b
funC:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.3
IL_0003: add
IL_0004: stloc.0 // s
IL_0005: ldarg.0
IL_0006: ldarg.0
IL_0007: mul
IL_0008: stloc.1
IL_0009: ldloc.0 // s
IL_000A: ldloc.1
IL_000B: ble.s IL_0011
IL_000D: ldc.i4.3
IL_000E: nop
IL_000F: br.s IL_0013
IL_0011: ldc.i4.1
IL_0012: nop
IL_0013: ldc.i4.1
IL_0014: add
IL_0015: ret
我觉得这种行为很奇怪。我曾认为,只有当存在
inline
关键字时,编译器才应该内联。有没有任何引用提到过它?关键字inline
是一种强制编译器内联函数的方法,因此允许函数将类型作为参数并提高性能。编译器没有理由不内联函数,因为它认为适合发布版本。我不知道有哪种优化编译器特别要求您使用“inline”关键字,使其能够通过内联进行优化。只有在发布模式下,编译器才会这样做。在调试模式下,没有内联优化。这看起来更像是在编译时运行“常量”操作。内联版本将包含更多的代码。@leppie是对的,“常量折叠”是您在此处寻找的术语。@leppie我更改了测试代码,因此编译器不应在此处执行常量折叠。
funC:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.3
IL_0003: add
IL_0004: stloc.0 // s
IL_0005: ldarg.0
IL_0006: ldarg.0
IL_0007: mul
IL_0008: stloc.1
IL_0009: ldloc.0 // s
IL_000A: ldloc.1
IL_000B: ble.s IL_0011
IL_000D: ldc.i4.3
IL_000E: nop
IL_000F: br.s IL_0013
IL_0011: ldc.i4.1
IL_0012: nop
IL_0013: ldc.i4.1
IL_0014: add
IL_0015: ret