2015-12-23 18 views
6

ProblemWird mit delete und anschließend .push() auf einen Array-Effekt Leistung/Speicherverbrauch?

delete auf einem Array-Elemente Mit ihm aus dem Array zu entfernen, ist der einzige Weg, ich bin bewusst ein Element aus einem Array zu entfernen, so dass ein .forEach() Aufruf den Index überspringt.

Fragen

  • Hat die delete auf einem Index verwenden, exampleArray[i] zum Beispiel ein nachfolgendes exampleArray.push() bewirken, dass der Speicher Verbrauch des Array-Objekts erhöhen?
  • Wie funktioniert löschen ein Objekt Effekt der Garbage Collector?

  • Gibt es eine effizientere Methode, ein exampleArray eines Elements zu entfernen?

Beispiel der ehemaligen

var exampleArray = []; 
var n = 500; 

//Does this line imply a memory allocation? 
exampleArray.length = n; 

exampleArray.fill("Lorem Ipsum", 0); 

exampleArray.forEach(function(cur, ind, arr) { 
    if(ind % 4 === 0) { 
    delete arr[ind]; //Actually deletes the object itself, index no longer exists 
    //Length does not change, however. Does available memory? 
    } 
}, this); 

n /= 4; 

//Where, in memory, are these placed? 
while(n--) exampleArray.push("amet dolor"); 

Jede Hilfe ist willkommen, danke.

+3

Ihre Annahmen sind alle ziemlich falsch. 'delete' ist nicht der einzige Weg, um einen Index aus einem Array zu entfernen, in der Tat, es tut dies überhaupt nicht, und ist nicht einmal für Arrays gedacht? Wie wirkt sich das auf den Garbage Collector und alles andere aus? – adeneo

+0

Ich habe keine Vermutungen gemacht, obwohl es sich anhört wie du es hast. Ich sagte, es sei die einzige Art und Weise, auf die ich mich bewusst war, mich aufzuklären? –

+1

@AndrueAnderson Wenn Sie nach kurzen und süßen Antworten auf Ihre Fragen suchen, sind sie 1) nein 2) es nicht 3) [] .splice – Andbdrew

Antwort

7

Ist die auf einem Index löschen verwenden, exampleArray[i] zum Beispiel bewirken, dass ein nachfolgendes exampleArray.push() den Speicherverbrauch des Array-Objekts erhöhen?

push erhöht den Speicherverbrauch, unabhängig davon, ob ihm ein delete vorausgegangen ist oder nicht. Gewöhnlich. Wenn die Engine Speicherplatz für zusätzliche Elemente zugewiesen hat, würde dies möglicherweise nicht der Fall sein. Wenn Sie sich vorstellen, dass die Engine den von delete geöffneten Speicherplatz irgendwie wiederverwenden könnte, um zu vermeiden, dass auf dem nächsten push zusätzlicher Speicher zugewiesen wird, höchstwahrscheinlich nicht.

Wie wirkt sich das Löschen eines Elements auf den Garbage Collector aus?

Das gelöschte Element unterliegt GC, wenn es nicht anderweitig im Gültigkeitsbereich bleibt.

Gibt es eine effizientere Methode, ein exampleArray eines Elements zu entfernen?

Sie müssen entscheiden, ob Sie mit einem Sparse-Array enden möchten. Wenn Sie nicht, und wie Sie forEach usw. über die Löcher springen, dann delete ist am schnellsten. Wenn Sie das Array um das gelöschte Element komprimieren möchten, z. B. splice, sind die Kosten wahrscheinlich doppelt so hoch.

Engines implementieren verschiedene Strategien, um Arrays intern darzustellen und manchmal zwischen ihnen umzuschalten - zum Beispiel, wenn ein Array einen bestimmten Grad an Spärlichkeit erreicht. Jeder Motor wird eine andere Strategie haben. Der einzige zuverlässige Weg, um diese Art von Leistungsfragen zu beantworten, ist die Durchführung von Leistungstests oder das Lesen der Engine-Quelle.

Der entscheidende Punkt bei GC ist, dass Sie sich keine Sorgen machen müssen. Sie wollen nicht in den Motor der zweiten Rate geraten. Sie könnten für einen Motor optimieren und feststellen, dass die Leistung eines anderen Motors schlechter wird.

Alle diese Fragen zur Mikrooptimierung sind nur relevant, wenn Sie eine Logik mit riesigen Datenobjekten haben, auf denen Sie Millionen von Operatoren ausführen. Wenn dies der Fall ist, können Sie Ihre eigene Datenstruktur rollen lassen.

+0

DANKE, dass Sie tatsächlich die Frage gelesen haben und den Kontext von .forEach() bemerken, der sich speziell mit spärlichen Arrays beschäftigt. Ich wünschte, ich könnte meinen Beitrag bearbeiten, um die Zeit anzugeben, die ich schätze. –

0

delete in Javascript hat eine sehr spezifische Funktion: removing a property from an object. Sie sollten nicht versuchen, Elemente aus einem Array zu entfernen.

Verwenden Sie stattdessen Array.prototype.splice:

zum Beispiel:

var arr = [1,2,3,4]; 
arr.splice(1, 1); 

console.log(arr); // [ 1, 3, 4 ] 

In Antwort auf die Frage nach der Garbage Collection, GC wird nicht durch Anrufe delete sofern sie nicht den einzigen Hinweis auf einen Gegenstand zu entfernen, passieren . delete zwingt GC nicht oder erleichtert es.

+0

Downvoter Pflege Kommentar? – Andbdrew

+0

Ich bin nicht der Downvoter, aber ich würde bemerken, dass ein Array-Element ** ist eine Eigenschaft auf ein Objekt. Es gibt sicherlich Anwendungsfälle für die Verwendung von delete, solange es Ihnen nichts ausmacht, mit einem spärlichen Array zu enden. –

+0

@torazaburo Ich denke in diesem Kontext ist der Index die Eigenschaft, nicht das eigentliche Element am Index – Andbdrew