我的編程範式教科書,Essential of Programming Languages (3rd ed),第1章有一個練習:內聯如何比遞歸定義更高效?
練習1.12
消除一個呼叫通過 其定義替換它,並簡化爲subst式-S-EXP在SUBST由此產生的 程序。結果將是不需要 subst-in-s-exp的子版本。這種技術被稱爲內聯,並被 優化編譯器使用。
原始代碼將有兩個功能:subst
和subst-in-sexp
基本上代替舊符號與輸入列表中的新符號的所有事件。
(define subst
(lambda (new old slist)
(if (null? slist) '()
(cons
(subst-in-s-exp new old (car slist))
(subst new old (cdr slist))))))
(define subst-in-s-exp
(lambda (new old sexp)
(if (symbol? sexp)
(if (eqv? sexp old) new sexp)
(subst new old sexp))))
回答這個問題是消除subst-in-sexp
,成爲這個
(define subst
(lambda (slist old new)
(cond
[ (null? slist) '()]
[ (eqv? (car slist) old) (cons new (subst (cdr slist) old new))]
[ else (cons (car slist) (subst (cdr slist) old new))])))
爲什麼在襯裏之外的更好,可能很多短(更少的空間)?遞歸的大小是否改變?換句話說,這種內聯是否會創建更少的堆棧元素?
此外,我怎樣才能使用這個想法使我的C++,Python和Java代碼更快?我可以輕鬆地擴展這個想法嗎?謝謝。
我在Scheme中標記了它(實際上是Racket),因爲這是書中語言的選擇。
是的,它應該減少少量堆棧幀的開銷,但是現在這不是真正的問題,代碼可讀性更重要,編譯器可能會將其優化爲完全不同的東西。 – AoeAoe 2012-02-13 08:25:41