是否有任何理由不使用INLINABLE pragma作为函数?

时间:2012-03-14 20:31:57

标签: haskell inline ghc pragma

documentation州:

  

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

     
      
  • 虽然INLINE说“请内联我”,但INLINABLE说“随意内插我;请自行决定”。换句话说,选择留给GHC,它使用与无编译指示函数相同的规则。与INLINE不同,该决定是在呼叫站点进行的,因此会受到内联阈值,优化级别等的影响。

  •   
  • 与INLINE类似,INLINABLE pragma保留原始RHS的副本以用于内联,并将其保留在接口文件中,而不管RHS的大小。

  •   
  • 使用INLINABLE的一种方法是结合内联特殊函数(第7.18节“特殊内置函数”)。调用内联f非常难以内联f。为了确保f可以内联,最好将f的定义标记为INLINABLE,以便GHC保证在不管它有多大的情况下展开展开。此外,通过将f注释为INLINABLE,可以确保f的原始RHS内联,而不是f GHC优化器产生的任何随机优化版本。

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

  •   
  • 与INLINE不同,可以在递归函数上使用INLINABLE pragma。主要原因是允许以后使用SPECIALIZE

  •   

它的缺点是什么?

它是否使接口文件更大,更大?是否使编译速度慢得多?

有没有理由我不应该在我写的每个导出函数上放置一个INLINABLE pragma?有没有理由GHC没有在我写的每个导出函数上放置一个INLINABLE pragma?

1 个答案:

答案 0 :(得分:49)

使用INLINABLE和完全不使用编译指示之间有三个区别:

  • 如果没有INLINABLE,接口文件中的定义是优化后的代码,而使用INLINABLE,则是您编写的代码(或多或少)。特别是,没有INLINABLE,GHC可能会将其他函数内联到函数的定义中。

  • 如果没有INLINABLE,GHC将忽略界面文件中的定义(如果它太大)。如果其他一些功能被内联到右侧,这可能很容易超过限制。

  • INLINABLE还会启用一些聪明的机器,这些机器会自动专门使用它们的重载函数,并与其他模块共享专用版本,这些模块可以传递导入创建专用版本的模块。