Übersicht
a.push(...b)
- begrenzte, schnelle, moderne Syntax
a.push.apply(a, b)
- begrenzt, schnell
a = a.concat(b)
unbegrenzt, langsam, wenn a
groß ist
for (let i in b) { a.push(b[i]); }
- unbegrenzt, langsam, wenn b
groß ist
Jedes Snippet ändert die a
zu erweitern mit b
.
Die "begrenzten" Schnipsel übergeben jedes Array-Element als Argument, und die maximale Anzahl der Argumente, die Sie einer Funktion übergeben können, ist begrenzt . Aus diesem Link geht hervor, dass a.push(...b)
ist zuverlässig, bis es etwa 32k Elemente in b
(die Größe von a
spielt keine Rolle).
Einschlägige MDN-Dokumentation: Verbreitungssyntax , .apply() , .concat() , .push()
Überlegungen zur Geschwindigkeit
Jede Methode ist schnell, wenn sowohl a
y b
sind klein, daher werden Sie in den meisten Webanwendungen die push(...b)
und damit fertig werden.
Wenn Sie mit mehr als ein paar tausend Elementen arbeiten, hängt es von der jeweiligen Situation ab, was Sie tun wollen:
- Sie fügen ein paar Elemente zu einem großen Array hinzu
push(...b)
ist sehr schnell
- Sie fügen viele Elemente zu einem großen Array hinzu
concat
ist etwas schneller als eine Schleife
- Sie fügen viele Elemente zu einem kleinen Array hinzu
concat
ist viel schneller als eine Schleife
- Sie sind in der Regel Hinzufügen von nur wenigen Elementen zu einem Array beliebiger Größe
Schleifen sind etwa so schnell wie die eingeschränkten Methoden für kleine Additionen, werfen aber nie eine Ausnahme, auch wenn sie nicht die leistungsfähigste ist, wenn Sie viele Elemente hinzufügen
- Sie schreiben eine Wrapper-Funktion, um immer die maximale Leistung zu erhalten
müssen Sie die Längen der Eingaben dynamisch überprüfen und die richtige Methode wählen, indem Sie vielleicht push(...b_part)
(mit Scheiben des großen b
) in einer Schleife.
Das hat mich überrascht: Ich dachte a=a.concat(b)
in der Lage wäre, ein schönes Memcpy von b
auf a
ohne sich die Mühe zu machen, einzelne Erweiterungsoperationen durchzuführen wie a.push(...b)
zu tun hätte und somit immer der Schnellste wäre. Stattdessen, a.push(...b)
ist viel, viel schneller, besonders wenn a
ist groß.
Die Geschwindigkeit der verschiedenen Methoden wurde in Firefox 88 unter Linux gemessen:
a = [];
for (let i = 0; i < Asize; i++){
a.push(i);
}
b = [];
for (let i = 0; i < Bsize; i++){
b.push({something: i});
}
t=performance.now();
// Code to test
console.log(performance.now() - t);
Parameter und Ergebnisse:
ms | Asize | Bsize | code
----+-------+-------+------------------------------
~0 | any | any | a.push(...b)
~0 | any | any | a.push.apply(a, b)
480 | 10M | 50 | a = a.concat(b)
0 | 10M | 50 | for (let i in b) a.push(b[i])
506 | 10M | 500k | a = a.concat(b)
882 | 10M | 500k | for (let i in b) a.push(b[i])
11 | 10 | 500k | a = a.concat(b)
851 | 10 | 500k | for (let i in b) a.push(b[i])
Beachten Sie, dass eine Bsize
von 500 000 ist der größte Wert, der von allen Methoden auf meinem System akzeptiert wird, deshalb ist er kleiner als Asize
.
Alle Tests wurden mehrfach durchgeführt, um festzustellen, ob es sich um Ausreißer oder repräsentative Ergebnisse handelt. Die schnellen Methoden sind in nur einem Durchgang fast unmessbar. performance.now()
Aber da die langsamen Methoden so offensichtlich sind und die beiden schnellen Methoden beide auf demselben Prinzip beruhen, brauchen wir es nicht mehrmals zu wiederholen, um Haare zu spalten.
Le site concat
Methode ist immer langsam, wenn eines der beiden Arrays groß ist, aber die Schleife ist nur langsam, wenn sie viele Funktionsaufrufe durchführen muss und es keine Rolle spielt, wie groß a
ist. Eine Schleife ist also ähnlich wie push(...b)
o push.apply
für kleine b
s, aber ohne zu brechen, wenn sie groß wird; wenn Sie sich jedoch der Grenze nähern, concat
wieder ein bisschen schneller ist.
10 Stimmen
Aus @Zahnbürste's Kommentar zu einer Antwort:
a.push(...b)
. Das Konzept ähnelt dem der ersten Antwort, wurde aber für ES6 aktualisiert.0 Stimmen
>>> a.push(...b)