gpt4 book ai didi

javascript - 为什么迭代 Set 的值会分配并产生垃圾?

转载 作者:行者123 更新时间:2023-12-04 14:07:16 25 4
gpt4 key购买 nike

昨天我问了this question关于如何在不分配的情况下迭代 Map。 v8 开发人员回复如下:

But if you're only interested in processing the values anyway, you can avoid it being created by iterating over just the values: for (let v of map.values()) {...} does not allocate any short-lived objects. The same is true for iterating over map.keys().

我正在尝试在测试中复制它,但我遇到了麻烦。这是我制作的一个演示,它重现了我在使用简单的 Set 时遇到的问题。将以下代码粘贴到一个空的 HTML 文件中的脚本标签中:

let a = new Set([ 1, 2, 3, 4, 5 ]);
let b = [ 1, 2, 3, 4, 5 ];

let sum = 0;

function setIterate() {
for (let item of a.values()) {
sum += item;
}
}

function arrayIterate() {
for (let i = 0; i < b.length; i++) {
sum += b[i];
}
}

setInterval(setIterate, 1);
// setInterval(arrayIterate, 1);

如果您打开此 HTML 文件然后按 Shift+Escape,它应该会打开 Chrome 任务管理器。如果您随后查看 Javascript 内存 列,您会看到内存随时间缓慢增长。

但是,如果您注释行 setInterval(setIterate, 1); 并取消注释行 setInterval(arrayIterate, 1); 并刷新页面,您将看到内存使用量保持不变。

也就是说,遍历 Set 会随着时间的推移产生垃圾堆积,而遍历数组则不会。

有什么方法可以迭代 Set 而不会随着时间的推移产生这种垃圾堆积?我正在开发一个浏览器游戏并在我的渲染循环中迭代许多 SetMaps 并且由于 GC 运行而偶尔出现帧峰值。

最佳答案

Why does iterating over a Set's values allocate and create garbage?

事实并非如此。对 setIterate 进行一百万次调用与 --trace-gc (在 d8node 中)显示零事件。 如果函数每次迭代分配一个字节(它不能;最小分配粒度是两个指针,即 8 个字节),那么年轻代至少会填满一次时间。

Is there any way to iterate a Set without producing this garbage build-up over time?

当然;例如你是怎么做的。

why does the Task Manager show memory increasing over time?

我不认为它会那样做。我已经完全按原样复制粘贴了您的代码片段,并让它静置几分钟;该选项卡的 Chrome 任务管理器的“JavaScript 内存”列没有变化一千字节。 (这实际上只能证明这个测试不是真正的压力测试:一旦 sum 超过 1<<30 ,它开始疯狂分配,但这不是因为集合或数组。 .)


大胆猜测:也许您安装了一些扩展程序,将代码注入(inject)每个页面并导致分配?无论如何,不​​管它是什么,它都不是 for..of -循环Set

关于javascript - 为什么迭代 Set 的值会分配并产生垃圾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67541538/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com