是否有任何理由不使用INLINABLE编译指示功能?
该文件指出:
函数f上的{ - #INLINABLE f# - }编译指示具有以下行为:
尽管INLINE表示“请将我内联”,但“可以插入”表示“可以随心所欲地使用您的自由裁量权”。 换句话说,选择留给GHC,它使用与无杂注函数相同的规则。 与INLINE不同,该决定是在呼叫站点进行的,因此将受到内联阈值,优化级别等的影响。
与INLINE一样,INLINABLE编译指示保留原始RHS的内联用途副本,并将其保存在接口文件中,而不管RHS的大小如何。
使用INLINABLE的一种方法是内联特殊功能(第7.18节“特殊内置功能”)。 内联调用f非常难以内联f。 为了确保f可以内联,最好将f的定义标记为INLINABLE,以便GHC保证揭示展开,而不管其大小如何。 此外,通过将f注释为INLINABLE,您可以确保f的原始RHS被内联,而不是GHC的优化器生成的任何随机优化版本。
INLINABLE pragma也适用于SPECIALIZE:如果将函数f标记为INLINABLE,那么随后可以在另一个模块中进行SPECIALIZE(请参见第7.16.8节“SPECIALIZE pragma”)。
与INLINE不同,在递归函数上使用INLINABLE编译指示是可以的。 主要原因是为了让以后使用SPECIALIZE
它的缺点是什么?
它是否使界面文件更大,更大? 它是否会使编译速度变慢?
有什么理由不应该在我写的每个导出函数上放置一个INLINABLE编译指示? 是否有任何理由GHC不会在我写的每个导出函数上放置一个INLINABLE编译指示?
使用INLINABLE和不使用编译指示符有三点区别:
没有INLINABLE,接口文件中的定义是优化后的代码,而使用INLINABLE时,它是您编写的代码(或多或少)。 特别是,如果没有INLINABLE,GHC可能会将其他函数内联到函数的定义中。
如果没有INLINABLE,如果它太大,GHC将会从接口文件中省略定义。 如果其他功能插入右侧,这可能会轻易超过极限。
INLINABLE还打开了一些巧妙的机制,它们在使用它们时自动专用重载函数,并与其他模块共享专用版本,这些模块可以传输导入创建专用版本的模块。
上一篇: Is there any reason not to use the INLINABLE pragma for a function?