在GHC中优化单构造函数数据类型的澄清

时间:2019-06-27 07:26:54

标签: haskell ghc

我正在阅读有关如何优化Haskell代码的内容,并遇到了有关Single-constructor datatypes in GHC的注释。

节选:

  

GHC喜欢单构造函数数据类型,例如元组。将单构造函数数据类型传递给严格函数时,可以将其解压缩。例如,给定此功能:

f (x,y) = ...
     

GHC的严格性分析器将检测到f在其参数中是严格的,并像这样编译函数:

f z = case z of (x,y) -> f' x y
f' x y = ...
     

其中f称为包装器,f'称为工作器。包装器到处都是内联的,因此,例如,如果您有这样的对f的调用:

... f (3,4) ...
     

这最终将被编译为

... f' 3 4 ...
     

元组已完全优化。

这是否意味着我应该遍历程序并将所有函数参数包装到一个元组中?无论如何,当元组被展开时,我真的看不到这是一种优化。

这是INLINE编译指示的替代方法吗?我应该同时使用吗?只有一个?更好吗?

1 个答案:

答案 0 :(得分:11)

  

无论如何,当元组被展开时,我真的看不到这是一种优化。

那是的优化:元组被解包。 IOW,最终运行的程序根本不会包含任何元组,而只包含两个参数的函数调用。

人们可能还会对此表示更悲观的说法:从头开始,元组本质上对性能不利。这是因为tuple参数需要三个指针间接寻址:整个tuple的thunk,fst元素的thunk和snd元素的thunk。因此,原则上,为了提高性能,将数据包装到元组中是一个非常糟糕的主意。 (最好将其放在具有严格字段的​​data结构中。)当然,除非您确实确实需要在所有这些地方都懒惰。

然而,这就是引用的全部内容,实际上,在GHC中使用元组通常还是可以的,因为如果可以证明不是,则通常可以优化间接寻址实际需要的。