【问题标题】:Cross-module inlining of internal modules内部模块的跨模块内联
【发布时间】:2026-01-15 06:20:08
【问题描述】:

我有一个带有很多内部模块的 cabal 包(other-modules 字段)。我相信我会从内联其中的大部分函数中受益。

我是否必须通过所有插入 pragma 或 GHC 和 Cabal 足够聪明来自己进行内联?如果是,那么这种内联将如何执行?如果否则我必须通过插入一个编译指示,我应该更喜欢哪个:INLINEINLINABLE(或者甚至可能是合成的inline function) - 出于什么原因?

【问题讨论】:

  • 你衡量过哪些函数受益于内联吗?
  • 没有。我只是从设计的角度得出这样的结论。该包基本上是作为一个多层次的组合来实现的,即很多功能只是来自其他模块的更简单的功能的组合,这些功能是内部的。很多人不用分解就可以实现这样的功能,所以我认为编译器可以为我做这些。

标签: haskell optimization inline ghc cabal


【解决方案1】:

GHC 在高水平优化方面会做得很好。

如果在检查 Core 和分析后,您确定某些函数没有被内联,那么您可以使用 INLINABLE 或 INLINE 来增加内联发生的可能性。

Recall那个

INLINE pragma 的主要作用是声明函数的“成本”非常低。正常的展开机器将非常热衷于内联它。

当 INLINE 表示“请内联我”时,INLINABLE 表示“随意内联我;请自行决定”

INLINABLE 通常是更好的选择,因为您不知道所有呼叫站点的外观。

但是,只有在您分析并且对性能不满意,并且可以证明通过内联提高了性能时,这样做才有意义。

【讨论】:

  • 谢谢。所以基本上,Cabal 向 GHC 提供的 other-modulesexposed-modules 没有任何不同?我只是希望它们能够更积极地优化(并因此内联),因为它不会影响包 API。
  • 不,Cabal 对如何优化包中的模块没有具体影响。