2016-05-27 6 views

Antwort

3

Es sollte keinen Leistungsunterschied geben. Der einzige Unterschied zwischen ihnen ist der Umfang der Variablen, der zur Kompilierzeit behandelt wird. Wenn es nur eine Variable gibt, gibt es absolut keinen Unterschied.

3

Wie Barmar betonte, sollte es bei "produktionsfertigen" Lisps keinen Leistungsunterschied geben.

Für CLISP, die beide diese produzieren die gleiche (Bytecode) Montage:

(defun foo (x) (let ((a x) (b (* x 2))) (+ a b))) 
(defun bar (x) (let* ((a x) (b (* x 2))) (+ a b))) 

Obwohl für Nicht-optimierende, einfache Dolmetscher (oder Compiler auch) dort sehr gut einen Unterschied sein könnte, z.B.

;; Possible macro expansion for foo's body 
(funcall #'(lambda (a b) (+ a b)) x (* x 2)) 
;; Possible macro expansion for bar's body 
(funcall #'(lambda (a) (funcall #'(lambda (b) (+ a b)) (* x 2))) x) 

mit mehreren lambdas, sowie die (vermeidbare) Schließung: wahrscheinlich effizienter jeder mit einem einzelnen Parameter implementiert wird als mehrere Lambdas weil let* und let könnte so einfach Makros und ein einziges Lambda mit mehreren Parametern ist über a könnte die zweite Erweiterung weniger "effizient" machen.

Wenn nur eine Bindung verwendet wird, sollte es auch dann keinen Unterschied geben.

Aber wenn Sie eine Implementierung verwenden, die let* (oder let) nicht optimiert, dann ist es wahrscheinlich kein Problem, die Leistung überhaupt zu diskutieren.

+0

Ich kann keine Dokumentation in der Hyperspec sehen, die die redundante Nutzung von 'let *' zu 'let' erfordert. Selbst wenn alle aktuellen Lisps identischen kompilierten Code bilden, wäre es immer noch ein De-facto-Standard, genau wie Sie wirklich kein Tail Call annehmen können Optimierung. – Sylwester

Verwandte Themen