78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
// bench/churn.ts
|
|
import { Bench } from "tinybench";
|
|
import { type Box, box } from "./../engine/lib/box.ts";
|
|
import {
|
|
createDictionary,
|
|
deleteEntry,
|
|
getEntry,
|
|
setEntry,
|
|
} from "./../engine/lib/Dictionary.ts";
|
|
import MapArray from "./../engine/lib/MapArray.ts";
|
|
|
|
const bench = new Bench({ name: "churn", time: 1000 });
|
|
|
|
const SIZE = 999;
|
|
const baseData: Array<[string, Box<number>]> = [];
|
|
{
|
|
let i = SIZE;
|
|
while (i-- > 0) baseData.push([String(i), box(i)]);
|
|
}
|
|
|
|
// Churn keys: a rotating window of "new" entities not in the base set,
|
|
// so every set/delete pair actually does real insert+remove work
|
|
// rather than repeatedly hitting the same already-resident key.
|
|
const CHURN_N = 100;
|
|
const churnKeys = Array.from({ length: CHURN_N }, (_, i) => `churn-${i}`);
|
|
|
|
let sink = 0; // anti-DCE: something observable reads this later
|
|
|
|
function freshMapArray() {
|
|
return new MapArray(structuredClone(baseData));
|
|
}
|
|
function freshDictionary() {
|
|
return createDictionary(structuredClone(baseData));
|
|
}
|
|
function freshMap() {
|
|
return new Map(structuredClone(baseData));
|
|
}
|
|
|
|
// Each task rebuilds nothing per-iteration except doing insert+remove
|
|
// on a fixed churn window against a persistent SIZE-element base structure —
|
|
// this mirrors "N entities steady-state, M entering/leaving per frame".
|
|
const ma = freshMapArray();
|
|
const dict = freshDictionary();
|
|
const map = freshMap();
|
|
|
|
bench
|
|
.add("MapArray churn (set+delete)", () => {
|
|
for (const key of churnKeys) {
|
|
ma.set(key, box(1));
|
|
}
|
|
for (const key of churnKeys) {
|
|
ma.delete(key);
|
|
}
|
|
sink += ma.entries().length;
|
|
})
|
|
.add("Dictionary churn (set+delete)", () => {
|
|
for (const key of churnKeys) {
|
|
setEntry(dict, [key, box(1)]);
|
|
}
|
|
for (const key of churnKeys) {
|
|
deleteEntry(dict, key);
|
|
}
|
|
sink += dict.entries.length;
|
|
})
|
|
.add("Map churn (set+delete)", () => {
|
|
for (const key of churnKeys) {
|
|
map.set(key, box(1));
|
|
}
|
|
for (const key of churnKeys) {
|
|
map.delete(key);
|
|
}
|
|
sink += map.size;
|
|
});
|
|
|
|
await bench.run();
|
|
console.table(bench.table());
|
|
console.log("sink (ignore):", sink);
|