Das heißt, wenn ich die aktuelle Zeit als Index für das Array verwende:
array[Date.getTime()] = value;
Wird der Interpreter alle Elemente von 0 bis jetzt instanziieren? Machen es verschiedene Browser anders?
Ich erinnere mich, dass es früher einen Fehler im AIX- Kernel gab, der auf Anfrage Pseudo-ttys erzeugte, aber wenn Sie "echo> / dev / pty10000000000" sagten, wurde / dev / pty0, / dev / pty1, .... und dann tot umfallen. Auf Messen hat es Spaß gemacht, aber ich möchte nicht, dass dies meinen Kunden passiert.
javascript
sparse-matrix
Beere
quelle
quelle
Antworten:
Wie genau JavaScript-Arrays implementiert werden, ist von Browser zu Browser unterschiedlich, sie greifen jedoch im Allgemeinen auf eine spärliche Implementierung zurück - höchstwahrscheinlich dieselbe, die für den Eigenschaftszugriff auf reguläre Objekte verwendet wird -, wenn die Verwendung eines tatsächlichen Arrays ineffizient wäre.
Sie müssen jemanden mit mehr Wissen über bestimmte Implementierungen fragen, um zu beantworten, was genau die Verschiebung von dicht zu dünn auslöst, aber Ihr Beispiel sollte absolut sicher sein. Wenn Sie ein dichtes Array erhalten möchten, sollten Sie den Konstruktor mit einem expliziten Längenargument aufrufen und hoffen, dass Sie tatsächlich eines erhalten.
In dieser Antwort finden Sie eine detailliertere Beschreibung von olliej.
quelle
foo = new Array(10000)
. Dies soll jedoch funktionieren :foo = Array.apply(null, {length: 10});
.Ja, sind Sie. Sie sind intern tatsächlich Hash-Tabellen, sodass Sie nicht nur große Ganzzahlen, sondern auch Zeichenfolgen, Gleitkommazahlen oder andere Objekte verwenden können. Alle Schlüssel werden über in Zeichenfolgen konvertiert,
toString()
bevor sie dem Hash hinzugefügt werden. Sie können dies mit einem Testcode bestätigen:Anzeigen:
Beachten Sie, wie ich die
for...in
Syntax verwendet habe, die nur die tatsächlich definierten Indizes enthält. Wenn Sie den allgemeinerenfor (var i = 0; i < array.length; ++i)
Iterationsstil verwenden, treten offensichtlich Probleme mit nicht standardmäßigen Array-Indizes auf.quelle
length
Eigenschaftlength
ist nur infor..in
Schleifen unsichtbar, weil dasDontEnum
Flag gesetzt ist; In ES5 wird das Eigenschaftsattribut aufgerufenenumerable
und kann explizit überObject.defineProperty()
String
; Alles andere, was Sie in den IndextoString()
eingeben, wird -ed. Kombinieren Sie dies mit der ganzzahligen Ungenauigkeit einer großen Zahl und es bedeutet, wenn Sie festlegena[9999999999999999]=1
,a[10000000000000000]
wird 1 (und viele weitere überraschende Verhaltensweisen) sein. Die Verwendung von Nicht-Ganzzahlen als Schlüssel ist sehr unklug, und beliebige Objekte sind direkt verfügbar.Sie können das Problem vermeiden, indem Sie eine Javascript-Syntax verwenden, die für diese Art von Dingen entwickelt wurde. Sie können es als Wörterbuch behandeln, aber mit der Syntax "für ... in ..." können Sie sie alle erfassen.
quelle
Javascript-Objekte sind spärlich und Arrays sind nur spezialisierte Objekte mit einer automatisch gepflegten Längeneigenschaft (die tatsächlich größer ist als der größte Index, nicht die Anzahl der definierten Elemente) und einigen zusätzlichen Methoden. Sie sind so oder so sicher; Verwenden Sie ein Array, wenn Sie zusätzliche Funktionen benötigen, und ansonsten ein Objekt.
quelle
Die Antwort lautet, wie es normalerweise bei JavaScript der Fall ist, "es ist ein bisschen seltsamer ...".
Die Speichernutzung ist nicht definiert und jede Implementierung darf dumm sein. Theoretisch
const a = []; a[1000000]=0;
könnte Megabyte Speicher brennen, wie könnteconst a = [];
. In der Praxis vermeidet sogar Microsoft diese Implementierungen.Justin Love weist darauf hin, dass das Längenattribut der höchste Indexsatz ist. ABER es wird nur aktualisiert, wenn der Index eine Ganzzahl ist.
Das Array ist also spärlich. ABER integrierte Funktionen wie redu (), Math.max () und "for ... of" durchlaufen den gesamten Bereich möglicher ganzzahliger Indizes von 0 bis zur Länge und besuchen viele, die "undefiniert" zurückgeben. ABER 'for ... in'-Schleifen können wie erwartet funktionieren und nur die definierten Schlüssel besuchen.
Hier ist ein Beispiel mit Node.js:
Geben:
Aber. Es gibt weitere Eckfälle mit Arrays, die noch nicht erwähnt wurden.
quelle
Die Sparseness (oder Dichte) kann für NodeJS mit dem nicht standardmäßigen process.memoryUsage () empirisch bestätigt werden .
Manchmal ist der Knoten klug genug, um das Array spärlich zu halten:
Manchmal entscheidet sich der Knoten dafür, ihn dicht zu machen (dieses Verhalten könnte in Zukunft möglicherweise optimiert werden):
Dann wieder spärlich:
Vielleicht muss die Verwendung eines dichten Arrays, um ein Gefühl für den ursprünglichen AIX-Kernel-Fehler zu bekommen, mit einem erzwungen werden Range-Alike werden :
Denn warum nicht umfallen lassen?
quelle
Sie können es sein, aber sie müssen es nicht immer sein, und sie können bessere Leistungen erbringen, wenn sie es nicht sind.
Hier ist eine Diskussion darüber, wie eine Indexinstanz in einer Array-Instanz getestet wird: https://benmccormick.org/2018/06/19/code-golf-sparse-arrays/
Dieser Code Golf Gewinner (wenige Zeichen) ist:
Grundsätzlich wird das Array nach indizierten Einträgen
!!
durchsucht, während der Längenwert dekrementiert und der gehärtete Boolesche Wert des falschen / wahrheitsgemäßen numerischen Ergebnisses zurückgegeben wird (wenn der Akkumulator vollständig auf Null dekrementiert wird, ist der Index vollständig gefüllt und nicht dünn). Die oben genannten Einschränkungen von Charles Merriam sollten ebenfalls berücksichtigt werden, und dieser Code behandelt sie nicht. Sie gelten jedoch für Hash-Zeichenfolgeneinträge, die auftreten können, wenn Elemente zugewiesen werden, beiarr[var]= (something)
denen var keine Ganzzahl war.Grund für die Sorge um die Index-Spärlichkeit sind die Auswirkungen auf die Leistung, die zwischen den Skript-Engines unterschiedlich sein können. Hier wird die Erstellung / Initialisierung von Arrays ausführlich diskutiert: Was ist der Unterschied zwischen "Array ()" und "[]" beim Deklarieren eines JavaScript ? Array?
Eine aktuelle Antwort auf diesen Beitrag enthält einen Link zu diesem tiefen Einblick, wie V8 versucht, Arrays durch Markieren zu optimieren, um (erneutes) Testen auf Eigenschaften wie Spärlichkeit zu vermeiden: https://v8.dev/blog/elements-kinds . Der Blog-Beitrag stammt aus dem 17. September und das Material unterliegt einigen Änderungen, aber die Aufschlüsselung nach Auswirkungen auf die tägliche Entwicklung ist nützlich und klar.
quelle