在数组上使用 delete 和随后的 .push() 会影响性能/内存消耗吗?

Does using delete and subsequently .push() on an array effect performance / memory consumption?

问题

在数组元素上使用 delete 将其从数组中删除是我知道的从数组中删除元素的唯一方法,这样 .forEach() 调用会跳过索引。

问题

前者的例子

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");

感谢任何帮助,谢谢。

delete in javascript 有一个非常特殊的函数:removing a property from an object。您不应尝试使用它从数组中删除项目。

而是使用 Array.prototype.splice:

例如:

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

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

在回答有关垃圾收集的问题时,GC 不受调用 delete 的影响,除非它们碰巧删除了对某个对象的唯一引用。 delete 不强制或促进 GC。

Does using the delete on an index, exampleArray[i] for example, cause a subsequent exampleArray.push() to increase the memory consumption of the array object?

push 会增加内存消耗,无论其前面是否有 delete。通常。如果引擎为额外的项目预先分配了存储空间,也许它不会。如果您认为引擎可能会以某种方式重新使用 delete 打开的 space 以避免在下一个 push 上分配额外的内存,那么很可能不会。

How does deleting an element effect the garbage collector?

如果删除的元素不在范围内,则它会受到 GC 的影响。

Is there a more efficient way of ridding an exampleArray of an element?

您必须决定是否介意以稀疏数组结尾。如果你不这样做,并且正如你指出的 forEach 等,跳过这些漏洞,那么 delete 是最快的。如果要压缩已删除元素周围的数组,例如使用 splice,成本可能会高出 2 倍。

引擎在内部实现不同的数组表示策略,有时会在它们之间切换——例如,当数组达到特定的稀疏程度时。每个引擎都有不同的策略。回答这类性能问题的唯一可靠方法是 运行 性能测试,或阅读引擎源代码。

他们关于 GC 的关键点是您不必担心它。您不想对引擎进行事后猜测。您可以优化一个引擎,然后发现另一个引擎的性能变差了。

所有这些微优化问题只有在您的逻辑涉及要在其上执行数百万个运算符的庞大数据对象时才有意义。如果是这样的话,可能是你想推出自己的数据结构。