7 Stimmen

Werden in einer Schleife alle Operationen in der Endbedingung in jeder Iteration ausgewertet?

Im folgenden Code:

for (var i = 0; i < object.length; i++){  
    ....  
}  

führt die Operation durch object.length jedes Mal in der Iteration ausgewertet werden?
Es wäre am sinnvollsten, wenn die Sprache dies einmal auswerten und das Ergebnis speichern würde. Ich habe jedoch einen Code gelesen, bei dem jemand die Operation vor Beginn der Schleife ausgewertet und in einer Variablen gespeichert hat, die in der Endbedingung verwendet wurde.
Wird dies in verschiedenen Sprachen unterschiedlich gehandhabt? Gibt es spezielle Informationen für Javascript?

8voto

Matthew Flaschen Punkte 266507

Das hängt natürlich von der Sprache ab. Für JavaScript verlangt die Spezifikation (ECMAScript §12.6.3), dass es jedes Mal ausgewertet wird. Zur Optimierung könnte eine spezielle JavaScript-Laufzeitumgebung einen oder mehrere der Längenaufrufe auslassen, wenn sie nachweisen kann, dass sich das Ergebnis nicht ändert.

3voto

Pointy Punkte 387467

Das hängt ganz von der Sprache ab und (möglicherweise) davon, was in der Schleife steht. Der Compiler/Interpreter ist möglicherweise nicht in der Lage, mit Sicherheit festzustellen, dass die Eigenschaft "Länge" nicht durch etwas in der Schleife verändert wird.

Bei Javascript ist es eine sichere Sache, dass es neu bewertet wird. Eine einfache Eigenschaft Referenz wie das ist wahrscheinlich nicht so schlecht, aber so etwas wie ein Funktionsaufruf könnte ein Leistungsproblem sein. bearbeiten Um das klarzustellen: Mit "Funktionsaufruf" meine ich jede Form von Code, der die Bedingung für den Schleifenabbruch auf eine Weise berechnet, die so aufwendig ist, dass Sie ein schlechtes Gewissen bekommen, wenn Sie das bei jeder Iteration tun.

Also (entschuldigen Sie mein jQuery),

for (var i = 0; i < $('.foo').length; ++i) { /* ... */ }

würde bei jeder Iteration eine Durchquerung des gesamten DOM erfordern.

1 Stimmen

Funktionsaufrufe selbst stehen in dynamischen Sprachen nicht in direktem Zusammenhang mit Leistungsproblemen; Funktionskörper könnten z.B. eingefügt werden.

1 Stimmen

Und eine "einfache Eigenschaftsreferenz" könnte der Aufruf einer komplexen Getter-Funktion sein (obwohl sie in diesem Fall einfach sein sollte).

0 Stimmen

@Chris - oh ja; was ich hätte sagen sollen, war "Funktionsaufrufe, die viel Arbeit machen". Ich kann das klarstellen.

2voto

Mark Byers Punkte 761508

Die Bedingung muss bei jeder Iteration der Schleife neu ausgewertet werden, da sich der Wert theoretisch innerhalb des Schleifenkörpers geändert haben könnte.

2voto

casablanca Punkte 68114

Ein intelligenter Compiler könnte automatisch für diesen Fall optimieren, sondern eine statische Analyse durchführen, um festzustellen, dass die Länge wird nicht innerhalb der Schleife zu ändern, ist in JavaScript extrem schwierig. Aus diesem Grund kann man sagen, dass in den meisten Fällen object.length wird in der Tat in jeder Iteration neu ausgewertet.

Andererseits ist es für den Programmierer oft einfacher herauszufinden, dass sich die Länge sicher nicht ändern wird, und wenn man wirklich (ich meine, wirklich ) um die Leistung besorgt sind, könnten Sie die Länge vor dem Beginn der Schleife berechnen und speichern.

2voto

Andrew Hodgkinson Punkte 3711

Wenn die Reihenfolge für Sie keine Rolle spielt, können Sie rückwärts iterieren. In diesem Fall brauchen Sie die chaotische temporäre Variable, die die Länge enthält, nicht. Die 立ち上がり Bedingung der Schleife wird nur einmal ausgewertet (es wäre natürlich sinnlos, sie erneut auszuwerten, wenn die Schleife bereits begonnen hat!). Anhand eines Beispiels aus einer früheren Antwort:

for (var i = $('.foo').length - 1; i >= 0; i--) { /* ... */ }

Ich weiß, dass ich diese Frage erst jetzt beantworte, nachdem sie gestellt wurde, aber sie wird in den Google-Suchergebnissen für verwandte Suchanfragen immer noch weit oben angezeigt, und keine der vorhandenen Antworten scheint diesen alternativen Ansatz zu empfehlen.

0 Stimmen

Oder for (var i = $('.foo').length; i --> 0;) { /* ... */ } für zusätzliche Internet-Punkte ;)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X