The book在第 1 章中定义了 block 结构,允许您“打包”define
位于过程定义内。
考虑这个mean-square
定义例如:
(define (mean-square x y)
(define (square x) (* x x))
(define (average x y) (/ (+ x y) 2))
(average (square x) (square y)))
当我运行(mean-square 2 4)
时我正确地得到 10
.
我的问题是,内部定义(在这个玩具案例中的 square
和 average
)是否每次运行我调用 mean-square
通过口译员进行程序?如果是这样,那不是效率低下吗?如果没有,为什么?
最佳答案
如果代码编译得有些幼稚,可能会产生一些开销。原因是内部函数是在一个全新的词法环境中定义的,该环境在每次进入函数时都会重新实例化。在抽象语义中,每次调用函数时,都必须捕获新的词法闭包并将其连接到该环境框架中的正确位置。
因此,归结为编译器可以优化掉多少内容。例如,它可以注意到这两个函数实际上都没有引用周围的词法环境。 (这些函数中的x
和y
引用是它们自己的参数,而不是周围均方
的参数)。这意味着它们都被移动到顶层而不改变语义:
(define (__anon1 x) (* x x))
(define (__anon2 x y) (/ (+ x y) 2))
(define (mean-square x y)
(define square __anon1)
(define average __anon2)
(average (square x) (square y)))
从现在起,square
和 average
实际上是简单的别名(由编译器生成的全局实体的别名,编译器知道它们不会被任何东西操纵)在其控制之外),它们表示的值可以通过以下方式传播:
(define (mean-square x y)
(__anon2 (__anon1 x) (__anon1 y)))
关于方案的 block 结构效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58827404/