对数组使用delete和后续的.push()会影响性能/内存消耗

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

本文关键字:影响 性能 内存 push 数组 delete      更新时间:2023-09-26

问题

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

问题

  • 在索引(例如exampleArray[i])上使用delete,导致后续exampleArray.push()增加内存数组对象的消耗
  • 删除对象是如何影响垃圾收集器的?

  • 有没有一种更有效的方法可以消除exampleArray中的要素

前者的示例

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

感谢您的帮助。

对索引(例如exampleArray[i])使用delete是否会导致后续的exampleArray.push()增加数组对象的内存消耗?

无论CCD_ 9之前是否有CCD_。通常如果引擎为其他项目预先分配了存储空间,也许它不会。如果您设想引擎可能能够以某种方式重用delete打开的空间,以避免在下一个push上分配额外的内存,那么很可能不会。

删除元素对垃圾收集器有何影响?

如果已删除的元素未保留在作用域中,则它将受到GC的约束。

有没有一种更有效的方法可以去除exampleArray中的元素?

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

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

GC的关键是你不必担心它。你不想对引擎进行事后猜测。你可以针对一台发动机进行优化,然后发现另一台发动机的性能变得更差。

只有当您有涉及巨大数据对象的逻辑时,所有这些微观优化问题才是相关的,您在这些对象上执行数百万个运算符。如果是这种情况,那么您可能希望滚动自己的数据结构。

javascript中的

delete有一个非常特殊的功能:从对象中删除属性。您不应该尝试使用它从数组中删除项。

相反,请使用Array.prototype.splice:

例如:

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

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