Maximale Größe eines Arrays in Javascript

107

Kontext: Ich erstelle eine kleine Site, die einen RSS-Feed liest und den Feed im Hintergrund aktualisiert / überprüft. Ich habe ein Array zum Speichern der anzuzeigenden Daten und ein anderes zum Speichern der IDs der angezeigten Datensätze.

Frage: Wie viele Elemente kann ein Array in Javascript enthalten, bevor die Dinge langsam oder träge werden? Ich sortiere das Array nicht, verwende aber die inArray-Funktion von jQuery, um einen Vergleich durchzuführen.

Die Website wird weiterhin ausgeführt und aktualisiert, und es ist unwahrscheinlich, dass der Browser so oft neu gestartet / aktualisiert wird.

Wenn ich darüber nachdenken sollte, einige Datensätze aus dem Array zu löschen, was ist der beste Weg, um einige Datensätze nach einem Limit zu entfernen, z. B. 100 Elemente.

sehr schön hinzugefügt
quelle
3
Sie werden wahrscheinlich mehr Probleme mit dem Browser haben, der Speicher aus Symbolleisten verliert als aus dem JS-Code. :) Firefox 4 Ich zeige mit dem Finger auf dich.
Epascarello
1
Wie oft überprüfen Sie das Array (ex 2s Intervall)? Was macht träge aus (ex> 500ms)? Welche Größenordnung hat Ihr Array (z. B. Tausende, Millionen, Milliarden)?
zzzzBov
2
Führen
VirtualTroll
Ich werde das Array jede Minute überprüfen und aktualisieren. Und ja, träge wäre ein Performance-Hit, der das Laden und Überprüfen sowie andere Animationen auf der Seite bewirkt, die schwer zu definieren sind. Entschuldigung!
hinzugefügt
@Amine danke für den Link, sieht so aus, als ob diese Website mein neuer bester Freund sein wird :)
hinzugefügt

Antworten:

152

Die maximale Länge bis "es wird träge" hängt vollständig von Ihrem Zielcomputer und Ihrem tatsächlichen Code ab. Sie müssen also auf dieser (diesen) Plattform (en) testen, um festzustellen, was akzeptabel ist.

Die maximale Länge eines Arrays gemäß der ECMA-262 5th Edition-Spezifikation ist jedoch aufgrund der abstrakten ToUint32- Operation durch eine vorzeichenlose 32-Bit-Ganzzahl gebunden , sodass das längste mögliche Array 2 32 -1 = 4.294.967.295 = 4,29 Milliarden Elemente haben kann .

Maerics
quelle
13
@ Barkermn01: Die ECMA-262 5th Edition-Spezifikation verwendet die abstrakte Operation ToUint32, um die Länge eines Arrays bei jeder Operation zu überprüfen, die seine Länge ändert. Daher halte ich die zugrunde liegende Architektur des Computers (oder Webbrowsers) für irrelevant.
Maerics
1
hrm schön gerade gelesen, dass ein toller 64Bit Browser dann sinnlos
flammt
3
@ Barkermn01, 64-Bit-Browser haben noch viele andere Verbesserungen. Denken Sie daran, dass ein Javascript-Interpreter nicht das einzige ist, was ein Browser tut.
Rasiermesser Sturm
1
Wowzer hätte nicht erwartet, dass es so hoch sein würde. OK schön ich denke mir geht es gut!
hinzugefügt
Tatsächlich kann ein Array höchstens 4294967295 (2 ^ 31-1) Elemente enthalten. Siehe stackoverflow.com/a/12766547/396458
NullUserException
26

Sie müssen das Array nicht trimmen, sondern müssen es einfach als Ringpuffer (Index% maxlen) adressieren. Dadurch wird sichergestellt, dass das Limit nie überschritten wird (die Implementierung eines Ringpuffers bedeutet, dass Sie nach Erreichen des Endes wieder zum Anfang zurückkehren - das Ende des Arrays kann nicht überschritten werden).

Beispielsweise:

var container = new Array ();
var maxlen = 100;
var index = 0;

// 'store' 1538 items (only the last 'maxlen' items are kept)
for (var i=0; i<1538; i++) {
   container [index++ % maxlen] = "storing" + i;
}

// get element at index 11 (you want the 11th item in the array)
eleventh = container [(index + 11) % maxlen];

// get element at index 11 (you want the 11th item in the array)
thirtyfifth = container [(index + 35) % maxlen];

// print out all 100 elements that we have left in the array, note
// that it doesn't matter if we address past 100 - circular buffer
// so we'll simply get back to the beginning if we do that.
for (i=0; i<200; i++) {
   document.write (container[(index + i) % maxlen] + "<br>\n");
}
Lelanthran
quelle
4
Kluge Idee, aber auf diese Weise können Sie Daten überschreiben, Indizes verwirren und möglicherweise zu seltsamem Verhalten führen.
John Ktejik
9
Die Idee ist, einen Ringpuffer zu implementieren, also ja - Sie "vergessen" absichtlich alte Daten (dafür wird ein Ringpuffer verwendet) und das hat der Fragesteller verlangt.
Lelanthran
1
Ich war nur gelangweilt, um SO zu klicken und fand diese Antwort. Ich liebe die Technik mit dem Überschreiben von Indizes nach Bedarf.
Kyle Hotchkiss
5

Sie können so etwas versuchen, um die Länge zu testen und zu kürzen:

http://jsfiddle.net/orolo/wJDXL/

var longArray = [1, 2, 3, 4, 5, 6, 7, 8];

if (longArray.length >= 6) {
  longArray.length = 3;
}

alert(longArray); //1, 2, 3

orolo
quelle
2
Ich habe Slice verwendet, da ich vom Anfang des Arrays an trimmen musste, danke.
hinzugefügt
3

Wie @maerics sagte, bestimmen Ihr Zielcomputer und Ihr Browser die Leistung.

Für einige Zahlen aus der realen Welt wird auf meinem Chromebook für Unternehmen 2017 der Vorgang ausgeführt:

console.time();
Array(x).fill(0).filter(x => x < 6).length
console.timeEnd();
  • x=5e4 dauert 16ms, gut genug für 60fps
  • x=4e6 dauert 250ms, was auffällt, aber keine große Sache ist
  • x=3e7 dauert 1300ms, was ziemlich schlecht ist
  • x=4e7 dauert 11000 ms und weist zusätzliche 2,5 GB Speicher zu

Rund 30 Millionen Elemente sind also eine harte Obergrenze, da die Javascript-VM bei 40 Millionen Elementen von einer Klippe fällt und den Prozess wahrscheinlich zum Absturz bringen wird.

Carl Walsh
quelle
2

Ich habe ein Leistungsframework erstellt, das Millionen von Datensätzen manipuliert und grafisch darstellt, und selbst dann lag die Latenz der Javascript-Berechnung in der Größenordnung von zehn Millisekunden. Ich glaube nicht, dass Sie sich Sorgen machen müssen, es sei denn, Sie machen sich Sorgen, die Grenzwerte für die Arraygröße zu überschreiten.

Rasiermessersturm
quelle
0

Es wird sehr browserabhängig sein. 100 Gegenstände klingen nicht nach einer großen Zahl - ich gehe davon aus, dass Sie viel höher gehen könnten. Tausende sollten kein Problem sein. Was ein Problem sein kann, ist der Gesamtspeicherverbrauch.

rjmunro
quelle
0

Ich habe schamlos einige ziemlich große Datensätze in den Speicher gezogen, und obwohl es träge wurde, dauerte es vielleicht 15 Mo Daten nach oben mit ziemlich intensiven Berechnungen für den Datensatz. Ich bezweifle, dass Sie Probleme mit dem Speicher haben werden, es sei denn, Sie haben intensive Berechnungen für die Daten und viele, viele Zeilen. Profiling und Benchmarking mit verschiedenen Scheinergebnismengen sind die beste Wahl, um die Leistung zu bewerten.

stefgosselin
quelle