Yesterday I asked this question on how to iterate over a Map
without allocating. A v8 developer replied with the following:
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().
I'm trying to replicate this in a test but I'm having trouble. Here's a demo I made that reproduces the problem I'm having with a simple Set
. Paste the following code in an empty HTML file in its script tags:
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);
If you open this HTML file and then hit Shift+Escape
it should open the Chrome Task Manager. If you then look at the Javascript Memory
column, you'll see the memory slowly growing over time.
However, if you comment the line setInterval(setIterate, 1);
and uncomment the line setInterval(arrayIterate, 1);
and refresh the page you'll see that the memory usage stays constant.
That is, iterating over a Set
produces garbage build-up over-time while iterating over an array does not.
Is there any way to iterate a Set without producing this garbage build-up over time? I'm developing a browser game and iterating over many Sets
and Maps
in my render loop and getting occasional frame-spikes due to the GC running.