it-swarm.com.de

Warum durchläuft ein Array schneller rückwärts als vorwärts?

Gegeben diesen Code:

var arr = [];

for (var i = 0; i < 10000; ++i)
    arr.Push(1);

Vorwärts

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

Rückwärts

for (var i = arr.length - 1; i >= 0; --i) {}

Hardcodierte Weiterleitung

for (var i = 0; i < 10000; ++i) {}

Warum ist Rückwärts so viel schneller?

Hier ist der Test: http://jsperf.com/array-iteration-direction

50
samccone

Weil Ihre Vorwärtsbedingung jedes Mal die Eigenschaft length Ihres Arrays erhalten muss, während die andere Bedingung nur auf "größer als Null" prüfen muss, eine sehr schnelle Aufgabe.

Wenn sich Ihre Array-Länge während der Schleife nicht ändert und Sie sich wirklich mit ns-perfomance beschäftigen, können Sie verwenden

for (var i=0, l=arr.length; i<l; i++)

Übrigens: Anstelle von for (var i = arr.length; i > 0; --i) könnten Sie for (var i = arr.length; i-- > 0; ) verwenden, das Ihr Array wirklich von n-1 bis 0 durchläuft, nicht von n bis 1.

81
Bergi

Denn im ersten Formular greifen Sie bei jeder Iteration einmal auf die Eigenschaft length des Arrays arr zu, im zweiten nur einmal.

8
rabusmar

Wenn Sie möchten, dass sie im gleichen Tempo ablaufen, können Sie dies für die Vorwärtsiteration tun.

for(var i=0, c=arr.length; i<c; i++){
}

Daher muss Ihr Skript bei jedem Schritt nicht die Länge des Arrays einnehmen.

6
tcak

Da bin ich mir nicht ganz sicher, aber hier ist meine Vermutung:

Für den folgenden Code:

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

Zur Laufzeit wird nach jedem Schleifendurchlauf eine Arr.length-Berechnung durchgeführt. Dies kann eine triviale Operation sein, wenn es sich um eine Einzeloperation handelt, kann sich jedoch auf mehrere/große Arrays auswirken. Können Sie Folgendes versuchen:

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

Im obigen Code berechnen wir die Array-Länge nur einmal und arbeiten mit dieser berechneten Zahl, anstatt die Längenberechnung immer wieder durchzuführen.

Wieder nur meine Gedanken hier rausbringen. Interessante Beobachtung in der Tat!

4
Gopal Nair

i > 0 ist schneller als i < arr.length und tritt bei jeder Iteration der Schleife auf.

Sie können den Unterschied folgendermaßen abmildern:

for (var i = 0, len = arr.length; i < len; ++i) {;
}

Dies ist immer noch nicht so schnell wie der Rückwärts-Gegenstand, aber schneller als Ihre Vorwärts-Option.

2
jfriend00

Und das sind gleich gut:

var arr= [], L= 10000;
while(L>-1) arr[L]= L--;

OR

var arr= [], i= 0;
while(i<10001) arr[i]=i++;
1
kennebec

tun Sie es wie unten, wird es auf die gleiche Weise durchgeführt. weil arr.length braucht Zeit in jeder Iteration vorwärts.

int len = arr.length;

vorwärts

for (var i = 0; i < len; ++i) {
}

rückwärts

for (var i = len; i > 0; --i) {
}
1
dku.rajkumar