// bench/churn-sweep.ts import { Bench } from "tinybench"; import { type Box, box } from "../engine/lib/box.ts"; import { createDictionary, deleteEntry, setEntry, } from "../engine/lib/Dictionary.ts"; import MapArray from "../engine/lib/MapArray.ts"; const SIZES = [100, 250, 500, 999, 2500, 5000, 10000]; const CHURN_N = 100; const churnKeys = Array.from({ length: CHURN_N }, (_, i) => `churn-${i}`); let sink = 0; function makeBaseData(size: number): Array<[string, Box]> { const data: Array<[string, Box]> = []; let i = size; while (i-- > 0) data.push([String(i), box(i)]); return data; } type Row = { structure: string; size: number; latencyNsAvg: number; latencyNsMed: number; }; const rows: Row[] = []; for (const size of SIZES) { const baseData = makeBaseData(size); const ma = new MapArray(structuredClone(baseData)); const dict = createDictionary(structuredClone(baseData)); const map = new Map(structuredClone(baseData)); const bench = new Bench({ name: `churn @ size=${size}`, time: 500 }); bench .add("MapArray", () => { for (const key of churnKeys) ma.set(key, box(1)); for (const key of churnKeys) ma.delete(key); sink += ma.entries().length; }) .add("Dictionary", () => { for (const key of churnKeys) setEntry(dict, [key, box(1)]); for (const key of churnKeys) deleteEntry(dict, key); sink += dict.entries.length; }) .add("Map", () => { for (const key of churnKeys) map.set(key, box(1)); for (const key of churnKeys) map.delete(key); sink += map.size; }); await bench.run(); for (const task of bench.tasks) { const res = task.result; if (!res) continue; rows.push({ structure: task.name, size, latencyNsAvg: res.latency.mean, latencyNsMed: res.latency.p50 ?? res.latency.mean, }); } console.log(`-- size=${size} done --`); console.table(bench.table()); } // CSV output const header = "structure,size,latency_ns_avg,latency_ns_med"; const csvLines = rows.map( (r) => `${r.structure},${r.size},${r.latencyNsAvg.toFixed(2)},${r.latencyNsMed.toFixed(2)}`, ); const csv = [header, ...csvLines].join("\n"); (await Deno.writeTextFile?.("churn-sweep.csv", csv)) ?? (await import("node:fs/promises")).then((fs) => fs.writeFile("churn-sweep.csv", csv), ); console.log("\nWrote churn-sweep.csv"); console.log("sink (ignore):", sink);