我正在尝试使用Scheme 中的代数数据类型对小型 lambda 演算进行编码。我希望它使用惰性求值,为此我尝试使用原语delay和force。然而,这对评估性能有很大的负面影响:小型测试用例的执行时间增加了 20 倍。
虽然我没想到懒惰会加速这个特定的测试用例,但我也没想到会出现巨大的减速。因此,我的问题是:是什么导致了延迟评估的巨大开销,以及如何在仍然进行延迟评估的同时避免这个问题?我已经很高兴能够将严格版本的执行时间缩短到 2 倍之内,但当然越快越好。
以下是我使用的测试用例的严格版本和惰性版本。该测试以一元表示法处理自然数:它构造一个2^24 sucs 后跟 a的序列zero,然后再次破坏结果。惰性版本是根据严格版本构建的,通过在适当的位置添加delay和,并添加- 绑定以避免多次强制参数。(我还尝试了一个版本,其中和是严格的,但其他函数是惰性的,但这比完全惰性的版本还要慢,所以我在这里省略了它。)forceletzerosuc
我使用compile-fileChez Scheme 9.5 编译了这两个程序,并.so使用petite --program. 严格版本的执行时间(仅限用户)为 0.578 秒,而惰性版本则需要 11,891 秒,几乎慢了 20 倍。
(define zero 'zero)
(define (suc x) (cons 'suc x))
(define one (suc zero))
(define two (suc one))
(define three (suc two))
(define (twice m)
(if (eq? m zero)
zero
(suc (suc …Run Code Online (Sandbox Code Playgroud)