Ich habe diesen Code ausgeführt und das folgende Ergebnis erhalten. Ich bin gespannt, warum []
es schneller geht.
console.time('using[]')
for(var i=0; i<200000; i++){var arr = []};
console.timeEnd('using[]')
console.time('using new')
for(var i=0; i<200000; i++){var arr = new Array};
console.timeEnd('using new')
- mit
[]
: 299ms - mit
new
: 363ms
Dank Raynos gibt es hier einen Benchmark für diesen Code und eine weitere Möglichkeit, eine Variable zu definieren.
javascript
performance
Mohsen
quelle
quelle
[]
istnew Array()
in Bezug auf den Quellcode gleichwertig , nicht Objekte, die aus Ausdrücken zurückgegeben werdenAntworten:
Weitere Antworten auf frühere Antworten ...
Aus der Sicht eines allgemeinen Compilers und ohne Berücksichtigung von VM-spezifischen Optimierungen:
Zuerst durchlaufen wir die lexikalische Analysephase, in der wir den Code tokenisieren.
Beispielsweise können die folgenden Token hergestellt werden:
Hoffentlich sollte dies Ihnen eine ausreichende Visualisierung bieten, damit Sie verstehen, wie viel mehr (oder weniger) Verarbeitung erforderlich ist.
Basierend auf den oben genannten Token wissen wir, dass ARRAY_INIT immer ein Array erzeugt. Wir erstellen daher einfach ein Array und füllen es aus. In Bezug auf die Mehrdeutigkeit hat die lexikalische Analysephase ARRAY_INIT bereits von einem Objekteigenschafts-Accessor (z. B.
obj[foo]
) oder Klammern in Zeichenfolgen / Regex-Literalen (z. B. "foo [] bar" oder / [] /) unterschieden.Das ist winzig, aber wir haben auch mehr Token mit
new Array
. Darüber hinaus ist noch nicht ganz klar, dass wir einfach ein Array erstellen wollen. Wir sehen den "neuen" Token, aber "neu" was? Wir sehen dann das IDENTIFIER-Token, das bedeutet, dass wir ein neues "Array" wollen, aber JavaScript-VMs unterscheiden im Allgemeinen kein IDENTIFIER-Token und keine Token für "native globale Objekte". Deshalb...Wir müssen die Scope-Kette jedes Mal nachschlagen, wenn wir auf ein IDENTIFIER-Token stoßen. Javascript-VMs enthalten für jeden Ausführungskontext ein "Aktivierungsobjekt", das das Objekt "Argumente", lokal definierte Variablen usw. enthalten kann. Wenn wir es im Aktivierungsobjekt nicht finden können, suchen wir die Bereichskette, bis wir den globalen Bereich erreichen . Wenn nichts gefunden wird, werfen wir a
ReferenceError
.Sobald wir die Variablendeklaration gefunden haben, rufen wir den Konstruktor auf.
new Array
ist ein impliziter Funktionsaufruf, und die Faustregel lautet, dass Funktionsaufrufe während der Ausführung langsamer sind (daher erlauben statische C / C ++ - Compiler "Function Inlining" - was JS JIT-Engines wie SpiderMonkey im laufenden Betrieb tun müssen).Der
Array
Konstruktor ist überladen. Der Array-Konstruktor ist als nativer Code implementiert, bietet also einige Leistungsverbesserungen, muss jedoch noch die Länge der Argumente überprüfen und entsprechend handeln. Darüber hinaus müssen wir den Typ des Arguments weiter überprüfen, falls nur ein Argument angegeben wird. neues Array ("foo") erzeugt ["foo"], während neues Array (1) [undefiniert] erzeugtUm alles zu vereinfachen: Mit Array-Literalen weiß die VM, dass wir ein Array wollen. Mit
new Array
muss die VM zusätzliche CPU-Zyklen verwenden, um herauszufinden, wasnew Array
tatsächlich funktioniert.quelle
Ein möglicher Grund ist,
new Array
dass eine Namenssuche erforderlich istArray
(Sie können eine Variable mit diesem Namen im Gültigkeitsbereich haben), während[]
dies nicht der Fall ist.quelle
Array
Ausgenommen sind sowohl ein Argumentlen
als auch mehrere Argumente. Wobei as[]
nur mehrere Argumente akzeptiert. Auch Firefox-Tests zeigen fast keinen Unterschied.var Array = window.Array
verbessert die Leistung desnew Array
Tests.Gute Frage. Das erste Beispiel wird als Array-Literal bezeichnet. Dies ist die bevorzugte Methode zum Erstellen von Arrays unter vielen Entwicklern. Es kann sein, dass der Leistungsunterschied dadurch verursacht wird, dass die Argumente des neuen Array () -Aufrufs überprüft und dann das Objekt erstellt werden, während das Literal direkt ein Array erstellt.
Der relativ kleine Leistungsunterschied unterstützt diesen Punkt, denke ich. Sie können den gleichen Test übrigens auch mit dem Objekt- und Objektliteral {} durchführen.
quelle
Das würde Sinn machen
http://www.dyn-web.com/tutorials/obj_lit.php
quelle
Interessant ist auch , dass die Verwendung eines Array-Konstruktors mit einer bestimmten Länge in Google Chrome 70+ viel schneller ist , wenn die Länge des Arrays im Voraus bekannt ist (Elemente werden unmittelbar nach der Erstellung hinzugefügt) .
" neues Array ( % ARR_LENGTH% ) " - 100% (schneller) !
" [] " - 160-170% (langsamer)
Den Test finden Sie hier - https://jsperf.com/small-arr-init-with-known-length-brackets-vs-new-array/2
Hinweis: Dieses Ergebnis wurde in Google Chrome v.70 + getestet . In Firefox v.70 und IE sind beide Varianten nahezu gleich.
quelle