Skip to content

Instantly share code, notes, and snippets.

@mubaraqwahab
Last active May 4, 2025 10:35
Show Gist options
  • Save mubaraqwahab/9419ad7d802d046e803150eec98b213e to your computer and use it in GitHub Desktop.
Save mubaraqwahab/9419ad7d802d046e803150eec98b213e to your computer and use it in GitHub Desktop.
Arrays vs iterators in JS
// Run the script like this: node --expose-gc index.mjs
import process from "node:process";
// Install with: npm i seedrandom
import seedrandom from "seedrandom";
function formatNumber(n, unit) {
return Intl.NumberFormat(undefined, {
unit: unit,
maximumFractionDigits: unit ? 2 : 0,
minimumFractionDigits: unit ? 2 : 0,
}).format(n);
}
function rangeArr(n) {
let result = [];
for (let i = 0; i < n; i++) {
result.push(i);
}
return result;
}
function* rangeIter(n) {
for (let i = 0; i < n; i++) {
yield i;
}
}
function benchmark(label, arrayFn, iterFn) {
const metrics = [];
for (let n = 10; n < 10 ** 7; n *= 10) {
globalThis.gc();
const arrayMemBefore = process.memoryUsage().heapUsed;
const arrayTimeBefore = process.hrtime.bigint();
arrayFn(n);
const arrayMemAfter = process.memoryUsage().heapUsed;
const arrayTimeAfter = process.hrtime.bigint();
globalThis.gc();
const iterMemBefore = process.memoryUsage().heapUsed;
const iterTimeBefore = process.hrtime.bigint();
iterFn(n);
const iterMemAfter = process.memoryUsage().heapUsed;
const iterTimeAfter = process.hrtime.bigint();
metrics.push({
"Array Length": formatNumber(n),
"Array Version - Memory (bytes)": formatNumber(
arrayMemAfter - arrayMemBefore,
"byte",
),
"Iterator Version - Memory (bytes)": formatNumber(
iterMemAfter - iterMemBefore,
"byte",
),
"Array Version - Performance (ms)": formatNumber(
arrayTimeAfter - arrayTimeBefore,
"millisecond",
),
"Iterator Version - Performance (ms)": formatNumber(
iterTimeAfter - iterTimeBefore,
"millisecond",
),
});
}
console.log(label);
console.table(metrics);
// Empty line
console.log();
}
function generateItems(n) {
const random = seedrandom(String(n));
return Array.from({ length: n }, (i) => ({
num: Math.round(random() * 10),
name: `Item ${i}`,
}));
}
benchmark(
"range()",
(n) => {
rangeArr(n).map((i) => `Item ${i}`);
},
(n) => {
rangeIter(n)
.map((i) => `Item ${i}`)
.toArray();
},
);
benchmark(
"Array manipulation",
(n) => {
generateItems(n)
.filter((o) => o.num % 2)
.slice(0, 10);
},
(n) => {
generateItems(n)
.values()
.filter((o) => o.num % 2)
.take(10)
.toArray();
},
);
range()
┌─────────┬──────────────┬────────────────────────────────┬───────────────────────────────────┬──────────────────────────────────┬─────────────────────────────────────┐
│ (index) │ Array Length │ Array Version - Memory (bytes) │ Iterator Version - Memory (bytes) │ Array Version - Performance (ms) │ Iterator Version - Performance (ms) │
├─────────┼──────────────┼────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────┼─────────────────────────────────────┤
│ 0 │ '10' │ '5,208.00' │ '6,632.00' │ '191,093.00' │ '192,233.00' │
│ 1 │ '100' │ '11,336.00' │ '19,480.00' │ '75,911.00' │ '143,418.00' │
│ 2 │ '1,000' │ '88,288.00' │ '166,328.00' │ '335,249.00' │ '427,469.00' │
│ 3 │ '10,000' │ '895,608.00' │ '795,696.00' │ '2,724,013.00' │ '6,463,651.00' │
│ 4 │ '100,000' │ '7,247,248.00' │ '9,092,336.00' │ '28,638,310.00' │ '35,458,023.00' │
│ 5 │ '1,000,000' │ '51,118,080.00' │ '65,501,648.00' │ '327,924,348.00' │ '292,029,168.00' │
└─────────┴──────────────┴────────────────────────────────┴───────────────────────────────────┴──────────────────────────────────┴─────────────────────────────────────┘
Array manipulation
┌─────────┬──────────────┬────────────────────────────────┬───────────────────────────────────┬──────────────────────────────────┬─────────────────────────────────────┐
│ (index) │ Array Length │ Array Version - Memory (bytes) │ Iterator Version - Memory (bytes) │ Array Version - Performance (ms) │ Iterator Version - Performance (ms) │
├─────────┼──────────────┼────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────┼─────────────────────────────────────┤
│ 0 │ '10' │ '42,032.00' │ '25,720.00' │ '1,765,414.00' │ '596,634.00' │
│ 1 │ '100' │ '56,896.00' │ '57,464.00' │ '536,254.00' │ '503,272.00' │
│ 2 │ '1,000' │ '385,184.00' │ '307,280.00' │ '3,430,901.00' │ '1,125,134.00' │
│ 3 │ '10,000' │ '3,066,976.00' │ '1,202,856.00' │ '7,180,805.00' │ '2,105,823.00' │
│ 4 │ '100,000' │ '13,918,536.00' │ '13,701,328.00' │ '28,858,188.00' │ '28,578,123.00' │
│ 5 │ '1,000,000' │ '94,220,632.00' │ '82,501,864.00' │ '510,760,420.00' │ '424,873,637.00' │
└─────────┴──────────────┴────────────────────────────────┴───────────────────────────────────┴──────────────────────────────────┴─────────────────────────────────────┘
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment