array.forJeder läuft schneller als native Iteration? Wie?

8

Ссылка

Es war mein Verständnis, dass Testfall 2 langsamer als Testfall 1 laufen sollte - ich wollte sehen, wie viel langsamer. Stellen Sie sich meine Überraschung vor, wenn ich sehe, dass es schneller läuft!

Was ist hier los? Optimierung hinter den Kulissen? Oder ist .für immer sauberer und schneller?

Testen in Chrome 18.0.1025.142 32-Bit unter Windows Server 2008 R2 / 7 64-Bit

    
Sean Anderson 02.04.2012, 18:17
quelle

5 Antworten

7

Es gibt viele Iterationsoptimierungen, die Ihrer for Schleife fehlen, wie zum Beispiel:

  • speichert die Array-Länge
  • iterate rückwärts
  • benutze ++ counter anstelle von counter ++

Das sind die, von denen ich gehört und benutzt habe, ich bin mir sicher, dass es mehr gibt. Wenn der Speicher mir richtig dient, ist die rückwärts iterierende while-Schleife die schnellste aller Schleifenstrukturen (in den meisten Browsern).

Sehen Sie diesen jsperf für einige Beispiele.

Bearbeiten: Links für Postfix-Präfix-Perf-Test und rückwärts iterieren . Ich konnte meine Referenz für die Verwendung von + = 1 anstelle von ++ nicht finden, daher habe ich sie aus der Liste entfernt.

    
jbabey 02.04.2012, 18:21
quelle
3

UPDATE:

Viele der alten Tricks in diesen Antworten sind großartig für die Interpretation von JS in älteren Browsern.

In jeder modernen JS-Implementierung, einschließlich aller modernen Browser, Node und der neuesten mobilen Webansichten, können Inline-Funktionen tatsächlich vom JIT (JS-Compiler) zwischengespeichert werden, was forEach eine deutlich schnellere Option für die Array-Iteration darstellt. Früher war das Gegenteil der Fall, wenn das wiederholte Aufrufen einer Funktion wiederholt einen Aufbau- / Abbauprozess erforderte, der die Leistung einer nicht-trivialen Schleife stark beeinträchtigen könnte.

Für die beste Leistung würde ich vermeiden, auf etwas zu verweisen, das nicht als Argument übergeben oder in der Funktion selbst definiert wurde, wenn Sie es nicht müssen. Ich bin mir nicht 100% sicher, dass das wichtig ist, aber ich konnte sehen, warum das so ist.

Getter-Werte, die alle Arten von Suchprozessen beinhalten, wie Array-Längen oder DOM-Knoten-Eigenschaften, werden wahrscheinlich auch immer noch am besten im Cache zwischengespeichert.

Aber darüber hinaus würde ich versuchen, das grundlegende Prinzip der Arbeitsvermeidung einfach durchgehen zu lassen. Die Vorberechnung von Dingen, die nicht in einer Schleife neu berechnet werden müssen, oder das Zwischenspeichern eines Abfrage-Selektor-Ergebnisses auf var, anstatt wiederholt im DOM zu stöbern, sind gute Beispiele dafür. Zu hart zu versuchen, das JIT-Verhalten auszunutzen, wird wahrscheinlich ziemlich geheimnisvoll werden und wahrscheinlich nicht im Laufe der Zeit oder über alle JITs hinweg bestehen.

ALTE ANTWORT:

Okay, vergiss die Textwand. Aufzählungszeichen:

%Vor%
  • length wird zwischengespeichert und sofort in den Index

  • übernommen
  • Der Vorteil der Rückwärtsiteration in JS AFAIK ist die Vermeidung eines logischen Operators mit zwei Operanden. In diesem Fall bewerten wir nur eine Nummer. Es ist wahr oder es ist Null und falsch.

  • Ich finde es auch elegant.

Erik Reppen 02.04.2012 19:02
quelle
1

Das Lesen von length von array bei jeder Iteration kann langsam sein, aber forEach ist comomonly langsamer, weil Funktionsaufruf keine billige Operation in js ist.

PS: forEach ist 14% langsamer bei FF10.

    
kirilloid 02.04.2012 18:22
quelle
0

Sie sind ungefähr gleich für mich in Opera. Zu beachten ist, dass Ihre Bedingung in for () array.length ist. Wenn Sie die Länge des Arrays in einer Variablen zwischenspeichern und dann eine Schleife erstellen, sollten Sie eine bessere Leistung sehen.

    
Jordan 02.04.2012 18:22
quelle
0

Vielleicht ist for () langsamer, weil die Schleife 'array.length' für jede Iteration anwendet, um die Länge des Arrays zu erhalten.

Versuchen Sie:

%Vor%     
CoursesWeb 02.04.2012 18:29
quelle

Tags und Links