// Compiles and evaluates one runtime.js bundle in isolation, with node:vm, and reports // the median compile and evaluate time (ms) over several rounds, plus their ratio. // runtime.js assigns to `self` at its top level (it is written for a worker global // scope), so this script stands in a bare `self`; nothing else it touches at module // evaluation time is missing from Node's global object. // Needs --experimental-vm-modules. Usage: node --experimental-vm-modules // scripts/eval-budget.mjs [path/to/runtime.js] [rounds] globalThis.self = globalThis; import vm from "node:vm"; import { readFileSync } from "node:fs"; const path = process.argv[2] ?? "dist/runtime/runtime.js"; const rounds = Number(process.argv[3] ?? 40); const source = readFileSync(path, "utf8"); function once() { const t0 = performance.now(); const mod = new vm.SourceTextModule(source, { identifier: `eval-budget-${Math.random()}`, initializeImportMeta(meta) { meta.url = "file:///runtime.js"; }, }); const t1 = performance.now(); return mod.link(() => { throw new Error("runtime.js is bundled; it should import nothing"); }).then(() => { const t2 = performance.now(); return mod.evaluate().then(() => { const t3 = performance.now(); return { compile: t1 - t0, evaluate: t3 - t2 }; }); }); } const compile = []; const evaluate = []; for (let i = 0; i < rounds; i++) { const r = await once(); compile.push(r.compile); evaluate.push(r.evaluate); } function median(a) { const s = [...a].sort((x, y) => x - y); const n = s.length; return n % 2 ? s[(n - 1) / 2] : (s[n / 2 - 1] + s[n / 2]) / 2; } const compileMs = median(compile); const evaluateMs = median(evaluate); console.log(JSON.stringify({ path, rounds, compileMs, evaluateMs, ratio: evaluateMs / compileMs }));