2012-03-14 46 views
43

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

一个吱 - #可以内联F# - }在函数f编译有以下行为:

  • 虽然INLINE说: “请行内我” 时,可以内联说: “随时联系我,使用您的判断力”。换句话说,选择留给GHC,它使用与无杂注函数相同的规则。与INLINE不同,该决定是在呼叫站点进行的,因此将受到内联阈值,优化级别等的影响。

  • 与INLINE一样,INLINABLE编译指示保留用于内联目的的原始RHS的副本,它在接口文件中,不管RHS的大小如何。

  • 使用INLINABLE的一种方法是与内联特殊功能(第7.18节“特殊内置功能”)结合使用。内联调用f非常难以内联f。为了确保f可以内联,最好将f的定义标记为INLINABLE,以便GHC保证揭示展开,而不管其大小如何。此外,通过将f注释为INLINABLE,您可以确保f的原始RHS被内联,而不是GHC的优化器生成的任何随机优化版本。如果将函数f标记为INLINABLE,那么随后可以在另一个模块中进行SPECIALIZE(参见第7.16.8节“SPECIALIZE编译指示”)。

  • 与INLINE不同,可以在递归函数上使用INLINABLE杂注。最主要的原因做这样允许以后使用专门

什么是它的缺点吗?

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

是否有任何理由我不应该在我写的每个导出函数上放置一个INLINABLE编译指示?是否有任何理由GHC不会在我写的每个导出函数上放置一个INLINABLE编译指示?

回答

49

有使用可以内联,而不是使用编译所有之间的三点区别:

  • 没有可以内联,那云在接口文件中的定义是后优化代码,而与可以内联,它是你写的代码(或多或少)。特别是,如果没有INLINABLE,GHC可能会将其他函数内联到函数的定义中。

  • 如果没有INLINABLE,GHC将会从接口文件中省略定义,如果它太大。如果其他功能插入右侧,这可能会轻易超过极限。

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

+9

我想了解实际的后果。第一点意味着函数没有内联的地方,它会使用未优化的代码并且速度较慢?或者如果它被内联,它会变慢,但RULES不会触发?或者它有时会更快,有时会慢一些?关于第二点,将其包含在除磁盘空间以外的接口文件中是否有任何缺点?它们能变得如此之大以至于出现问题(磁盘很大)?重申:第三点,有什么理由说它不是一个没有光彩的好东西?它会导致代码量膨胀的问题? – glaebhoerl 2012-03-14 21:12:54

+4

我故意避免谈论实际的后果,因为大部分我不确定:-)我说服西蒙PJ添加了INLINABLE,因为我想要一个不会导致太多代码膨胀的INLINE变体,通过使用GHC已经非常复杂的启发式关于何时内联。要回答你的第一个问题:不,还会有编译到原始模块中的函数的优化版本(与INLINE一样),这将用于未内联的调用。在界面中包含大量的函数定义可能会降低速度。 – 2012-03-15 08:39:31

+0

嗯,好吧。如果有关于何时使用它以及何时不使用它的指导方针会很好,但我想我必须进行试验。 :) – glaebhoerl 2012-03-15 11:59:03

相关问题