我不记得我在哪里阅读它,但我对内联的理解是它在调试版本中被“关闭”(静态解析类型约束除外)。但事实并非如此,内联成员的断点永远不会被击中而踩到是不可能的。
由于在使用内联和不使用内联之间存在(轻微)语义差异,或许这也是在调试版本中强制执行内联的原因?对于我想在调试期间调查的内联函数,我目前使用类似这样的函数:
原始代码:
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。
答案 0 :(得分:2)
在几种情况下,没有遵循内联指令存在一个真正的问题。如您在问题中所述,F#核心库提供了(+) operator等功能,需要使用statically-resolved type parameters。 CLR的泛型运行时系统不支持这些类型的泛型。相反,F#编译器在编译时推断泛型类型参数,并为每个已解析的类型创建执行所必需的IL。
这是一个关键特性,并且忽略了所有inline
指令,这是一种非常规的启动,因为在很多情况下它意味着代码不会被编译。 --nooptimizationdata
通常会从生成的程序集中删除优化数据;它不会阻止程序集中的内联,但它可能会在引用inline
函数时禁止其他程序集内联。
还应该注意的是,Don Syme已经声明通常不需要使用inline
(在SRTP之外)并且可能是过早的性能优化,实际上可能妨碍编译器执行其操作自己的优化。