如何在F#中有条件地内联成员,或者完全关闭Debug构建中的内联

时间:2015-11-17 01:19:29

标签: debugging f# visual-studio-2015 inline f#-4.0

我不记得我在哪里阅读它,但我对内联的理解是它在调试版本中被“关闭”(静态解析类型约束除外)。但事实并非如此,内联成员的断点永远不会被击中而踩到是不可能的。

由于在使用内联和不使用内联之间存在(轻微)语义差异,或许这也是在调试版本中强制执行内联的原因?对于我想在调试期间调查的内联函数,我目前使用类似这样的函数:

原始代码:

type CE =
    static member inline map f = CE.bind (f >> Some)   // line is never hit

更新了代码

type CE =
    static member 
#if !DEBUG
            inline 
#endif
                map f =
        CE.bind (f >> Some)    // gets hit now when debugging

虽然这有效但很难看。是否有另一种可能性,即使用编译器开关或属性来打开/关闭它,或者是要求太多麻烦(即前面提到的静态解析类型参数,也许是用户定义的运算符的自动内联)

注意:我的主要用例实际上不是调试本身,而是对函数或成员进行计数,代替代码覆盖率报告。

使用F#4.0,.NET 4.5和Visual Studio 2015。

1 个答案:

答案 0 :(得分:2)

在几种情况下,没有遵循内联指令存在一个真正的问题。如您在问题中所述,F#核心库提供了(+) operator等功能,需要使用statically-resolved type parameters。 CLR的泛型运行时系统不支持这些类型的泛型。相反,F#编译器在编译时推断泛型类型参数,并为每个已解析的类型创建执行所必需的IL。

这是一个关键特性,并且忽略了所有inline指令,这是一种非常规的启动,因为在很多情况下它意味着代码不会被编译。 --nooptimizationdata通常会从生成的程序集中删除优化数据;它不会阻止程序集中的内联,但它可能会在引用inline函数时禁止其他程序集内联。

还应该注意的是,Don Syme已经声明通常不需要使用inline(在SRTP之外)并且可能是过早的性能优化,实际上可能妨碍编译器执行其操作自己的优化。