Frage zu SICP chpt 4.1: Wie beschleunigt (analysiere Ausdruck) die Geschwindigkeit von eval?

8

Ich lese den folgenden Abschnitt von SICP

Ссылка

Laut dem Text führt die folgende Umwandlung von eval zu einer Leistungsverbesserung, da ein Ausdruck, der viele Male ausgewertet wird, nur einmal analysiert wird?

%Vor%

Hier ist eine analyze -Funktion im Buch angegeben:

%Vor%

Ich verstehe nicht, warum das Buch sagt, dass analyze nur einmal ausgeführt wird. Ist nicht der Body von eval , was ((analyze exp) env)) ist, grundsätzlich zu sagen, dass jedes Mal, wenn eval aufgerufen wird, analyze mit exp als Parameter aufgerufen wird? Dies würde bedeuten, dass analyze jedes Mal aufgerufen wird, wenn eval aufgerufen wird.

Was stimmt nicht mit meinem Verständnis? Ich würde mich über Feedback freuen, danke!

    
wk1989 13.10.2010, 20:55
quelle

3 Antworten

5

Tatsächlich wird bei jedem Aufruf von eval mit Programmcode als Parameter der syntaktische Evaluator aufgerufen. Wenn jedoch eine Funktion innerhalb dieses Codes eine andere Funktion in diesem Code aufruft (oder sich im einfachsten Fall selbst durch Rekursion aufruft), erhält das innere apply den analysierten Ausdruck (der am Ende eine Lambda-Funktion ist) als ein Argument, anstatt ein Blob von Code, der syntaktisch erneut analysiert werden müsste, um ausgeführt zu werden.

    
Gintautas Miliauskas 13.10.2010 21:22
quelle
5

Gintautas 'Antwort ist richtig, aber vielleicht ist ein Beispiel in Ordnung. Angenommen, Sie haben einen Scheme-Dialekt entwickelt, der ein Schleifenkonstrukt enthält.

%Vor%

mit der offensichtlichen Semantik. Wenn Sie nun das naive eval aufrufen, um eine Schleife zu evaluieren, die zehnmal ausgeführt wird

%Vor%

Dann wird der Schleifenkörper zehn Mal analysiert. Mit der Version von eval , die die Analyse von der Auswertung trennt, ist der Schleifenkörper einmal analyze d und dann zehnmal ausgewertet.

Die Analysephase gibt eine Prozedur zurück, die in Ihrem Scheme-Interpreter schnell sein kann. Es könnte jedoch denkbar sein, alle Arten von Optimierungen vorzunehmen (Dead-Code-Analyse, JIT-Kompilierung ), um Code zu bearbeiten .).

    
Fred Foo 15.10.2010 15:12
quelle
2

larsmans 'Antworten sind sehr gut.

Als eine ergänzende Antwort kann man analyze(environ) auch als eine Curry-Form von eval(expr, environ) betrachten, in der der Parameter expr im Voraus übergeben wurde. In SICP können Sie den Beispielcode lesen:

%Vor%

Wenn Sie let (([var] [preprocessed stuff])) sehen, wird die Vorverarbeitung in einem Abschluss gespeichert, bis sie später benötigt wird, wenn environ übergeben wird.

    
ninjagecko 06.11.2011 11:45
quelle

Tags und Links