关于在 GHC 中优化单构造函数数据类型的说明

Clarification on optimizing Single-constructor datatypes in GHC

我在阅读有关如何优化我的 Haskell 代码的内容时,发现了一条关于 Single-constructor datatypes in GHC 的注释。

摘录:

GHC loves single-constructor datatypes, such as tuples. A single-constructor datatype can be unpacked when it is passed to a strict function. For example, given this function:

f (x,y) = ...

GHC's strictness analyser will detect that f is strict in its argument, and compile the function like this:

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

where f is called the wrapper, and f' is called the worker. The wrapper is inlined everywhere, so for example if you had a call to f like this:

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

this will end up being compiled to

... f' 3 4 ...

and the tuple has been completely optimised away.

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

这是 INLINE pragma 的替代方法吗?我应该同时使用两者吗?只有一个?一个更好吗?

I don't really see how this is an optimization when the tuple gets unwrapped anyway.

这就是优化:元组被展开。 IOW,最终运行的程序根本不包含元组,它只包含一个 two-argument 函数调用。

人们也可以用更悲观的术语来表达:从头开始,元组本质上对性能不利。这是因为元组参数需要 三个 指针间接寻址:整个元组的 thunk,fst 元素的 thunk,以及 snd 元素的 thunk。所以原则上,为了性能,将数据包装到元组中是一个非常糟糕的主意。 (最好将它放在 data 具有严格字段的​​结构中。)也就是说,当然,除非你真的需要在所有这些地方都懒惰。

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