The 文档 http://www.haskell.org/ghc/docs/latest/html/users_guide/pragmas.html states:
函数 f 上的 {-# INLINABLE f #-} 编译指示具有以下行为:
INLINE 表示“请内联我”,而 INLINABLE 则表示“随意内联我;请自行决定”。换句话说,选择权留给了 GHC,它使用与无编译指示函数相同的规则。与 INLINE 不同,该决定是在调用站点做出的,因此会受到内联阈值、优化级别等的影响。
与 INLINE 一样,INLINABLE 编译指示保留原始 RHS 的副本以用于内联目的,并将其保留在接口文件中,无论 RHS 的大小如何。
使用 INLINABLE 的一种方法是与特殊函数 inline 结合使用(第 7.18 节“特殊内置函数”)。调用 inline f 非常努力地尝试内联 f。为了确保 f 可以内联,最好将 f 的定义标记为 INLINABLE,这样 GHC 就能保证暴露展开,无论它有多大。此外,通过将 f 注释为 INLINABLE,您可以确保 f 的原始 RHS 是内联的,而不是 f GHC 优化器生成的任何随机优化版本。
INLINABLE pragma 也可以与 SPECIALISE 一起使用:如果将函数 f 标记为 INLINABLE,那么您随后可以在另一个模块中进行 SPECIALIZE(请参见第 7.16.8 节“SPECIALIZE pragma”)。
与 INLINE 不同,可以在递归函数上使用 INLINABLE 编译指示。这样做的主要原因是为了以后可以使用 SPECIALIZE
它有什么缺点呢?
它会使界面文件变得非常非常大吗?它会使编译速度变慢吗?
我有什么理由不应该在我编写的每个导出函数上放置 INLINABLE pragma 吗? GHC 是否有任何原因不在我编写的每个导出函数上添加 INLINABLE pragma?
使用 INLINABLE 和根本不使用编译指示之间存在三个区别:
如果没有 INLINABLE,接口文件中的定义就是代码after优化,而对于 INLINABLE,它是您编写的代码(或多或少)。特别是,如果没有 INLINABLE,GHC 可能会将其他函数内联到函数的定义中。
如果没有 INLINABLE,如果接口文件太大,GHC 将忽略该定义。如果其他一些函数内联到右侧,则很容易超出限制。
INLINABLE 还开启了一些巧妙的机制,可以自动专门化使用重载函数的地方,并与其他模块共享专门化版本,这些模块可传递导入创建专门化版本的模块。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)