有什么理由不使用INLINABLE编译指示function吗?

该文件指出:

函数f上的{ – #INLINABLE f# – } pragma具有以下行为:

  • 虽然INLINE说“请把我列入”,但是INLINABLE说:“随意联系我,使用你的自由裁量权”。 换句话说,select留给GHC,它使用与无杂注函数相同的规则。 与INLINE不同,该决定是在呼叫站点进行的,因此将受到内联阈值,优化级别等的影响。

  • 像INLINE一样,INLINABLE pragma保留了原始RHS的内联目的,并将其保存在接口文件中,而不pipeRHS的大小如何。

  • 使用INLINABLE的一种方法是与内联的特殊function(第7.18节“特殊内置function”)结合使用。 内联调用f很难内联f。 为了确保f可以内联,将f的定义标记为INLINABLE是一个好主意,这样GHC就可以保证揭示一个展开,而不pipe它有多大。 此外,通过将f注释为INLINABLE,可以确保f的原始RHS是内联的,而不是任何随机优化的GHC优化器生成的版本。

  • INLINABLE pragma也适用于SPECIALIZE:如果将函数f标记为INLINABLE,那么随后可以在另一个模块中进行SPECIALIZE(请参见第7.16.8节“SPECIALIZE pragma”)。

  • 与INLINE不同的是,在recursion函数中使用INLINABLE编译指示是可以的。 这样做的主要原因是为了让以后使用SPECIALIZE

它有什么缺点?

它是否使界面文件更大,更大? 它会使编译速度变慢吗?

有什么理由不应该在我写的每个导出的函数上放置一个INLINABLE编译指示? 有没有什么原因GHC不会在我写的每个导出的函数上放置一个INLINABLE编译指示?

使用INLINABLE和不使用编译指示符有三点区别:

  • 没有INLINABLE,接口文件中的定义是优化的代码,而使用INLINABLE时,它是您编写的代码(或多或less)。 特别是在没有INLINABLE的情况下,GHC可能会将其他函数内联到函数的定义中。

  • 如果没有INLINABLE,GHC将会从接口文件中忽略定义,如果它太大的话。 如果其他function被embedded到右侧,这可以轻易地将其推到极限。

  • INLINABLE还打开了一些巧妙的机制,它们在使用它们时自动专用重载函数,并与其他模块共享专用版本,这些模块可以传输导入创build专用版本的模块。