我正在阅读SICP的以下部分
http://mitpress.mit.edu/sicp/full-text/book/book-ZH-26.html#%_sec_4.1.7
根据文本,以下eval改进将提高性能,因为多次评估的表达式只会被分析一次?
(define (eval exp env)
((analyze exp) env))
Run Code Online (Sandbox Code Playgroud)
这是analyze本书中给出的函数:
(define (analyze-if exp)
(let ((pproc (analyze (if-predicate exp)))
(cproc (analyze (if-consequent exp)))
(aproc (analyze (if-alternative exp))))
(lambda (env)
(if (true? (pproc env))
(cproc env)
(aproc env)))))
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这本书说analyze只会运行一次.没有了身体eval,这是((analyze exp) env))基本上是说,每次eval被调用时,analyze将一个名为exp作为它的参数?这意味着analyze每次调用时eval都会调用它.
我的理解有什么问题?我将不胜感激任何反馈,谢谢!
实际上,每次eval使用程序代码作为参数调用时,都会调用语法赋值器.但是,当该代码中的函数调用该代码中的另一个函数时(或者,在最简单的情况下,它通过递归调用自身),内部apply将获得分析的表达式(最后是一个lambda函数)作为参数,而不是需要再次进行语法分析才能执行的代码块.
Gintautas的回答是正确的,但也许是一个例子.假设您已经开发了一个体现循环结构的Scheme方言
(do-n-times n expr)
Run Code Online (Sandbox Code Playgroud)
具有明显的语义.现在,当你打电话给天真eval来评估一个运行十次的循环时
(eval '(do-n-times 10 (print 'hello)))
Run Code Online (Sandbox Code Playgroud)
然后它会分析循环体十次.随着版本eval,从评估分离分析,循环体是analyzeð一次,然后评估十倍.
分析阶段回送一个过程,这可能会或不会在你的方案解释快.但是,可以想见,做各种优化的(死代码分析,JIT编译成机器代码,等等).
| 归档时间: |
|
| 查看次数: |
400 次 |
| 最近记录: |