我们有两个函数来计算给定数字的阶乘.第一个,!使用累加器样式.第二种,fact使用自然递归.
(define (! n0)
(local (;; accumulator is the product of all natural numbers in [n0, n)
(define (!-a n accumulator)
(cond
[(zero? n) accumulator]
[else (!-a (sub1 n) (* n accumulator))])))
(!-a n0 1)))
Run Code Online (Sandbox Code Playgroud)
和
(define (fact n)
(cond
[(= 0 n) 1]
[else (* n (fact (- n 1)))]))
Run Code Online (Sandbox Code Playgroud)
在第31节的底部,HtDP声明自然递归版本通常与累加器版本一样快,但不会说明原因.我对此做了一些阅读,似乎答案是"尾调优化/消除",但维基百科的文章似乎与HtDP的说法不一致,至少在性能方面.为什么会这样?
在工作中,递归样式更快.在家里,累加器风格更快.是否没有通用的启发式指导选择哪种风格通常是首选的?我知道累加器式的内存效率更高,但如果我们将讨论局限于性能,至少对我来说,目前还不清楚,哪个是更好的选择.
我已经考虑了这一点,并且不得不支持维基百科关于累积器式递归在一般情况下的优越性的文章.它不仅减少了堆栈/堆空间的使用,而且内存访问总是落后于寄存器访问,并且只有现在多核就在这里才能更加明显.尽管如此,HtDP证明在所有情况下都需要进行实际测试.
在练习12年1月18日HTDP,我一直在使用"本地"重新编写马克西功能.
;; maxi : non-empty-lon -> number
;; to determine the largest number on alon
(define (maxi alon)
(cond
[(empty? (rest alon)) (first alon)]
[else (local ((define m (maxi (rest alon))))
(cond
[(> (first alon) m) (first alon)]
[(> m (first (rest alon))) m]
[else (first (rest alon))]))]))
Run Code Online (Sandbox Code Playgroud)
我不确定为什么我会在"现实生活"中这样做,因为看起来这本书的版本更短,更清晰,也可能更快.
(define (maxi alon)
(cond
[(empty? (rest alon)) (first alon)]
[else (cond
[(> (first alon) (maxi (rest alon))) (first alon)]
[else (maxi (rest alon))])]))
Run Code Online (Sandbox Code Playgroud)
它是否意味着纯粹的教学运动?有经验的Schemer可以评论上面的代码吗?谢谢.
我正在使用具有"高级学生"语言设置的Racket,并且我很难尝试编写一个函数来执行函数,执行n次并报告每次运行所用的时间.这是我到目前为止所得到的.
(define (many n fn)
(cond
[(= n 0) true]
[else (many (sub1 n) (local ((define k (time fn))) k))]))
Run Code Online (Sandbox Code Playgroud)
我有一个函数叫做fact计算数字的阶乘.
(define (fact n)
(cond
[(= 0 n) 1]
[else (* n (fact (- n 1)))]))
Run Code Online (Sandbox Code Playgroud)
如果我评估(time (fact 10000)),我得到合理的结果cpu,real和gc时间,以及大量.一切都很好.
但是,当我尝试评估时,(many 3 (fact 10000))我得到:
cpu time: 0 real time: 0 gc time: 0
cpu time: 0 real time: 0 gc time: 0
cpu time: 0 real time: 0 gc time: 0
true
Run Code Online (Sandbox Code Playgroud)
fact尽管作为参数传递,为什么函数不进行评估?
lambda scheme functional-programming operator-precedence racket