繁体   English   中英

Haskell中的WHNF减少是否发生在编译时?

[英]Does the WHNF reduction in Haskell happen at Compile time?

AFAIU由Haskell compiler生成的目标文件应该是机器代码。 那么该目标文件是否具有原始AST的表示并在运行时减少它,或者这种减少是在编译时发生的,并且只有最终的WHNF值被转换为相应的机器代码。

我理解后者的编译时间是程序本身时间复杂度的函数,我认为不太可能。

有人可以清楚地解释运行时会发生什么以及在Haskell (GHC)的情况下编译时会发生什么?

编译器可以在运行时执行其所有减少的工作。 也就是说,生成的可执行文件可以具有(大)数据部分,其中整个程序AST被编码,以及(小)文本/代码部分具有在AST上操作的通用WHNF缩减器。

请注意,上述方法适用于任何语言。 例如,Python编译器也可以生成包含AST数据和通用reducer的可执行文件。 reducer将遵循语言的所谓小步语义 ,这是计算机科学中更为人熟知的概念(更具体地说,在编程语言理论中)。

但是,这种方法的表现会很差。

编程语言的研究人员致力于寻找更好的方法,从而导致抽象机器的定义。 本质上,抽象机是用于在较低级别设置中运行高级程序的算法。 通常,它利用一些数据结构(例如堆栈)来使过程更有效。 对于Haskell等函数式语言,众所周知的抽象机器包括:

问题本身远非微不足道。 已经有,并且我认为仍有研究使WHNF降低效率更高。

在GHC编译之后,每个Haskell定义都成为一系列汇编指令,它们操纵STG机器的状态。 周围没有AST,只有操作数据/闭包等的代码。

可以说,使用这些先进技术来提高性能以及大量优化是非常重要的。 然而,一个消极的后果是,很难理解原始代码的结果代码的性能,因为需要考虑抽象机器的工作方式(这是非常重要的)和优化(非常复杂)如今)。 在较小程度上,这也是大量优化C或C ++编译器的情况,在这种情况下,更难以了解何时触发优化。

最终,有经验的程序员(在Haskell,C,C ++或其他任何方面)将会理解其编译器的基本优化,以及正在使用的抽象机器的基本机制。 但是,我认为这不是一件容易掌握的事情。

在这个问题中,提到WHNF减少可以在编译时执行。 这只是部分正确,因为直到运行时才能知道源自IO动作的变量的值,因此减少只能在涉及这些值的运行时发生。 此外,执行减少也会使性能变差! 例如

let x = complex computation in x + x
-- vs
complex computation + complex computation

后者是减少前者的结果,但它重复了工作! 实际上,大多数抽象机器都使用惰性约简方法,这使得x在这种情况下只能计算一次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM