@cosyte/bench 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/environment.ts","../src/contract.ts","../src/spawn.ts","../src/stats.ts","../src/import-cost.ts","../src/suite.ts","../src/compare.ts","../src/reading.ts","../src/report.ts","../../test-utils/src/perf/contract.ts","../src/measure.ts","../src/results.ts","../src/main.ts","../src/cli.ts"],"names":["resolve","readFileSync","join","rmSync","mkdtempSync","tmpdir","writeFileSync","bytes","skipped","pct","latency","require","environment","pathToFileURL","relative"],"mappings":"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","file":"cli.mjs","sourcesContent":["/**\n * The machine a measurement was taken on. Every results document carries it, because a number\n * means nothing apart from its machine: ADR 0001 measured a significant shift from a runner image\n * update with no code change.\n *\n * Nothing here names a person: no host name, no user, no absolute path.\n *\n * @packageDocumentation\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { availableParallelism, cpus, loadavg, release, totalmem } from \"node:os\";\n\n/** Where a measurement ran. */\nexport interface Environment {\n readonly node: string;\n readonly v8: string;\n readonly platform: string;\n readonly arch: string;\n readonly osRelease: string;\n readonly cpuModel: string | null;\n readonly logicalCpus: number;\n readonly totalMemoryBytes: number;\n /** The cgroup CPU quota (`cpu.max`), when Linux reports one: a throttled container measures differently. */\n readonly cgroupCpuMax: string | null;\n /** Whether `NODE_OPTIONS` was set. Its value is not recorded; it can hold paths. */\n readonly nodeOptionsSet: boolean;\n /**\n * The 1, 5 and 15 minute load averages when the document was written (zeros where the platform\n * has none). A busy machine is a noisy one: this is how a reader tells.\n */\n readonly loadAverage: readonly number[];\n readonly runner: Runner;\n}\n\n/** The CI runner, when there is one. */\nexport interface Runner {\n readonly ci: boolean;\n /** `github-actions`, or `null` off CI. */\n readonly provider: string | null;\n /** `github-hosted` or `self-hosted` (`RUNNER_ENVIRONMENT`). */\n readonly environment: string | null;\n /** The runner image (`ImageOS`) and its version (`ImageVersion`). */\n readonly imageOS: string | null;\n readonly imageVersion: string | null;\n /**\n * A key for \"the same kind of machine\": the provider, image and architecture on CI, or\n * `local-<platform>-<arch>` off it. Results are only compared within one class.\n */\n readonly class: string;\n}\n\n/**\n * The cgroup CPU quota, or `null` where the file is absent (not Linux, or no cgroup v2 limit).\n *\n * @internal\n */\n// Stryker disable next-line StringLiteral: the default path is the machine's own file, present or not depending on the machine; tests pass a path.\nexport function readCgroupCpuMax(path = \"/sys/fs/cgroup/cpu.max\"): string | null {\n try {\n return String(readFileSync(path)).trim();\n } catch {\n return null;\n }\n}\n\n/**\n * Describe this machine and, from `env`, the CI runner.\n *\n * @internal\n */\nexport function environment(\n env: NodeJS.ProcessEnv = process.env,\n cgroupCpuMax: () => string | null = () => readCgroupCpuMax(),\n cpuList: () => readonly { readonly model: string }[] = cpus,\n load: () => readonly number[] = loadavg,\n): Environment {\n const cpu = cpuList()[0];\n const provider = env[\"GITHUB_ACTIONS\"] === \"true\" ? \"github-actions\" : null;\n const imageOS = env[\"ImageOS\"] ?? null;\n const runnerClass =\n provider === null\n ? `local-${process.platform}-${process.arch}`\n : `${provider}-${env[\"RUNNER_ENVIRONMENT\"] ?? \"unknown\"}-${imageOS ?? \"unknown\"}-${process.arch}`;\n return {\n node: process.version,\n v8: process.versions.v8,\n platform: process.platform,\n arch: process.arch,\n osRelease: release(),\n cpuModel: cpu === undefined ? null : cpu.model.trim(),\n logicalCpus: availableParallelism(),\n totalMemoryBytes: totalmem(),\n cgroupCpuMax: cgroupCpuMax(),\n nodeOptionsSet: (env[\"NODE_OPTIONS\"] ?? \"\") !== \"\",\n loadAverage: load().map((x) => Math.round(x * 100) / 100),\n runner: {\n ci: env[\"CI\"] === \"true\",\n provider,\n environment: env[\"RUNNER_ENVIRONMENT\"] ?? null,\n imageOS,\n imageVersion: env[\"ImageVersion\"] ?? null,\n class: runnerClass,\n },\n };\n}\n","/**\n * The benchmark constants, frozen.\n *\n * Every value here is fixed by the performance standard,\n * `documentation/decisions/0005-the-performance-standard.md` in the `config` repo, which says for\n * each one whether it was measured or chosen, and on what basis. The warmup rule is not here: it\n * is `PERF_CONTRACT` in `@cosyte/test-utils/perf` (ADR 0001 section 2), which `measure.ts` imports\n * and the build bundles, so the scaling gate and the benchmarks warm up by one rule kept in one\n * place.\n *\n * They are not tuning knobs and cannot be overridden per package. A comparison's false alarm rate\n * was measured with these values; change one and the measurement no longer describes the tool.\n *\n * @packageDocumentation\n */\n\n/** The benchmark constants. See {@link BENCH_CONTRACT}. */\nexport interface BenchContractShape {\n /** Timed samples per case per process. Each sample is whole passes over the corpus. */\n readonly SAMPLES: number;\n /** Minimum timed length of one sample, in milliseconds. A sample runs whole passes until it is reached. */\n readonly SAMPLE_MIN_MS: number;\n /** Rounds in one base against head comparison. Each round runs both sides once, in fresh processes. */\n readonly ROUNDS: number;\n /** One-sided error allowed at each end of the comparison's interval on the median ratio. */\n readonly ALPHA: number;\n /** The smallest slowdown a comparison will call a regression, as a fraction: 0.03 is 3%. */\n readonly THRESHOLD: number;\n /** Time budget for the latency calls of one case, in milliseconds. */\n readonly LATENCY_BUDGET_MS: number;\n /** Most latency calls taken for one case. */\n readonly LATENCY_MAX_CALLS: number;\n /** Fewest latency calls taken for one case, whatever the budget says. */\n readonly LATENCY_MIN_CALLS: number;\n /** A percentile q is reported only when at least this many calls lie above it: n(1 - q) >= 10. */\n readonly LATENCY_TAIL_CALLS: number;\n /** The median call must be at least this many timer reads long, or latency is skipped. */\n readonly LATENCY_TIMER_MULTIPLE: number;\n /** Most operations in the first allocation window. Halved while a garbage collection lands in a window. */\n readonly ALLOC_WINDOW_OPS: number;\n /** The first allocation window is cut to about this many milliseconds of operations, from the warmup's pace. */\n readonly ALLOC_WINDOW_MS: number;\n /** The young generation size the allocation process runs with, in MiB, so a window rarely collects. */\n readonly ALLOC_SEMI_SPACE_MIB: number;\n /** Calls measured one by one for the peak heap. */\n readonly PEAK_CALLS: number;\n /** Rounds in the long run that checks the heap stays flat. */\n readonly LONG_RUN_ROUNDS: number;\n /** Rounds at the start of the long run left out of the slope, while caches and compiled code settle. */\n readonly LONG_RUN_SETTLE_ROUNDS: number;\n /** Minimum length of one long run round, in milliseconds, fixed as a number of operations by the first. */\n readonly LONG_RUN_ROUND_MS: number;\n /** A long run whose fitted growth over the measured rounds reaches this many bytes is reported as growing. */\n readonly LONG_RUN_GROWTH_BYTES: number;\n /** A garbage collection round that reclaims less than this, in bytes, counts as settled (ADR 0001 section 8). */\n readonly GC_SETTLE_BYTES: number;\n /** Consecutive settled rounds needed (ADR 0001 section 8). */\n readonly GC_SETTLE_ROUNDS: number;\n /** Most garbage collection rounds before giving up (ADR 0001 section 8). */\n readonly GC_MAX_ROUNDS: number;\n /** Fresh processes timed for the cold import, for the target and for an empty module each. */\n readonly IMPORT_RUNS: number;\n /** The timing comparison may become a required check when A/A false alarms are under this rate. */\n readonly REQUIRED_FALSE_ALARM_RATE: number;\n /** The confidence that the false alarm rate is under the line, for the rule above. */\n readonly REQUIRED_CONFIDENCE: number;\n}\n\n/**\n * The frozen benchmark constants.\n *\n * @example\n * ```ts\n * import { BENCH_CONTRACT } from \"@cosyte/bench\";\n *\n * BENCH_CONTRACT.ROUNDS; // => 12\n * BENCH_CONTRACT.THRESHOLD; // => 0.03\n * ```\n */\nexport const BENCH_CONTRACT: BenchContractShape = Object.freeze({\n SAMPLES: 5,\n SAMPLE_MIN_MS: 50,\n ROUNDS: 12,\n ALPHA: 0.05,\n THRESHOLD: 0.03,\n LATENCY_BUDGET_MS: 2_000,\n LATENCY_MAX_CALLS: 5_000,\n LATENCY_MIN_CALLS: 20,\n LATENCY_TAIL_CALLS: 10,\n LATENCY_TIMER_MULTIPLE: 20,\n ALLOC_WINDOW_OPS: 256,\n ALLOC_WINDOW_MS: 100,\n ALLOC_SEMI_SPACE_MIB: 64,\n PEAK_CALLS: 20,\n LONG_RUN_ROUNDS: 30,\n LONG_RUN_SETTLE_ROUNDS: 5,\n LONG_RUN_ROUND_MS: 100,\n LONG_RUN_GROWTH_BYTES: 64 * 1024,\n GC_SETTLE_BYTES: 64 * 1024,\n GC_SETTLE_ROUNDS: 2,\n GC_MAX_ROUNDS: 7,\n IMPORT_RUNS: 20,\n REQUIRED_FALSE_ALARM_RATE: 0.01,\n REQUIRED_CONFIDENCE: 0.95,\n});\n","/**\n * Starting measuring processes and reading what they measured.\n *\n * @packageDocumentation\n */\n\nimport { spawn } from \"node:child_process\";\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type { Job, JobResult } from \"./child.js\";\nimport { BENCH_CONTRACT } from \"./contract.js\";\n\n/**\n * A run that could not produce a measurement. The command line reports it and exits 2.\n *\n * @example\n * ```ts\n * import { BenchError } from \"@cosyte/bench\";\n *\n * new BenchError(\"no result\").name; // => \"BenchError\"\n * ```\n */\nexport class BenchError extends Error {\n override readonly name = \"BenchError\";\n}\n\n/**\n * Where the built measuring processes live, beside this module in `dist`.\n *\n * @internal\n */\nexport const ENTRIES = Object.freeze({\n child: fileURLToPath(new URL(\"./child-entry.mjs\", import.meta.url)),\n importer: fileURLToPath(new URL(\"./import-entry.mjs\", import.meta.url)),\n});\n\n/**\n * How measuring processes are started. The defaults are the real ones; tests point `entry` at a\n * stand-in.\n *\n * @internal\n */\nexport interface SpawnOptions {\n /** The script the process runs. */\n readonly entry?: string;\n /** Flags for `node` before the script. */\n readonly execArgv?: readonly string[];\n /** Killed after this long, in milliseconds. */\n readonly timeoutMs?: number;\n}\n\n/**\n * The environment a measuring process gets: this one's, less what would change what it measures.\n * `NODE_V8_COVERAGE` would instrument it (a test runner sets it) and `NODE_COMPILE_CACHE` would\n * make a cold import warm.\n *\n * @internal\n */\nexport function childEnv(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {\n const out = { ...env };\n delete out[\"NODE_V8_COVERAGE\"];\n delete out[\"NODE_COMPILE_CACHE\"];\n return out;\n}\n\n/** What a process said, raw. */\ninterface ProcessOutcome {\n readonly code: number | null;\n readonly signal: string | null;\n readonly stderr: string;\n readonly timedOut: boolean;\n}\n\nconst STDERR_LIMIT = 16 * 1024;\n\n/**\n * Run `node <execArgv> <entry> <args>` with stdout discarded (the code under test may print), and\n * keep the last 16 KiB of stderr for a diagnostic.\n *\n * @internal\n */\nexport function runNode(\n entry: string,\n args: readonly string[],\n execArgv: readonly string[],\n timeoutMs: number,\n execPath: string = process.execPath,\n): Promise<ProcessOutcome> {\n return new Promise((resolve, reject) => {\n const child = spawn(execPath, [...execArgv, entry, ...args], {\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n env: childEnv(),\n });\n let stderr = \"\";\n let timedOut = false;\n child.stderr.on(\"data\", (chunk: Buffer) => {\n stderr = (stderr + String(chunk)).slice(-STDERR_LIMIT);\n });\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGKILL\");\n }, timeoutMs);\n child.on(\"error\", (error) => {\n // Stryker disable next-line all: an uncleared timer only keeps the event loop alive until it fires; killing a process that is gone does nothing.\n clearTimeout(timer);\n reject(error);\n });\n child.on(\"close\", (code, signal) => {\n // Stryker disable next-line all: as above, the timer's only effect after the process ended is to hold the event loop.\n clearTimeout(timer);\n resolve({ code, signal, stderr, timedOut });\n });\n });\n}\n\n/**\n * The flags a job's process starts with. Memory jobs need `gc()`; the allocation job also gets a\n * young generation large enough that a window of operations rarely collects.\n *\n * @internal\n */\nexport function flagsFor(job: Job): string[] {\n if (job.mode === \"timing\") return [];\n if (job.mode === \"heap\") return [\"--expose-gc\"];\n const mib = String(BENCH_CONTRACT.ALLOC_SEMI_SPACE_MIB);\n return [\"--expose-gc\", `--min-semi-space-size=${mib}`, `--max-semi-space-size=${mib}`];\n}\n\nfunction describe(job: Job): string {\n return `${job.mode} job for \"${job.case.benchmark} @ ${job.case.size}\"`;\n}\n\n/**\n * Run one job in a fresh process and return what it measured. Throws {@link BenchError} when the\n * process timed out, died, or wrote no result, with the tail of its stderr.\n *\n * @internal\n */\nexport async function runInChild(job: Job, options: SpawnOptions = {}): Promise<JobResult> {\n // Stryker disable next-line StringLiteral: the prefix only names the temporary directory.\n const dir = mkdtempSync(join(tmpdir(), \"cosyte-bench-\"));\n try {\n const jobFile = join(dir, \"job.json\");\n const outFile = join(dir, \"out.json\");\n writeFileSync(jobFile, JSON.stringify(job));\n const outcome = await runNode(\n options.entry ?? ENTRIES.child,\n [jobFile, outFile],\n options.execArgv ?? flagsFor(job),\n options.timeoutMs ?? 600_000,\n );\n if (outcome.timedOut) throw new BenchError(`the ${describe(job)} timed out`);\n let text: string;\n try {\n text = String(readFileSync(outFile));\n } catch {\n const how = outcome.signal === null ? `exit ${String(outcome.code)}` : outcome.signal;\n throw new BenchError(\n `the ${describe(job)} ended (${how}) without a result. Its stderr ends:\\n${outcome.stderr}`,\n );\n }\n const out = JSON.parse(text) as { ok: boolean; result?: JobResult; error?: string };\n if (!out.ok || out.result === undefined) {\n throw new BenchError(`the ${describe(job)} could not measure: ${String(out.error)}`);\n }\n return out.result;\n } finally {\n rmSync(dir, { recursive: true });\n }\n}\n","/**\n * The statistics the benchmarks report and judge by. Plain arithmetic with no dependencies, each\n * function small enough to check by hand against the worked numbers in its tests.\n *\n * @packageDocumentation\n */\n\n/**\n * A sorted copy, ascending. The input is not touched.\n *\n * @internal\n */\nexport function sortedCopy(xs: readonly number[]): number[] {\n return [...xs].sort((a, b) => a - b);\n}\n\n/**\n * The median: the middle value, or the mean of the two middle values. `NaN` for an empty vector,\n * so an empty measurement can never read as a fast one.\n *\n * @internal\n */\nexport function median(xs: readonly number[]): number {\n const s = sortedCopy(xs);\n const mid = Math.floor(s.length / 2);\n // An even length of at least 2 has both middle values. An empty vector takes the even branch and\n // reads two missing values, which is `NaN`: the empty answer, by arithmetic rather than a check.\n return s.length % 2 === 1\n ? (s[mid] as number)\n : ((s[mid - 1] as number) + (s[mid] as number)) / 2;\n}\n\n/**\n * A percentile by nearest rank: the smallest value with at least a fraction `q` of the values at or\n * below it. No interpolation, so every reported percentile is a value that was observed.\n *\n * @internal\n */\nexport function nearestRank(xs: readonly number[], q: number): number {\n if (xs.length === 0) return Number.NaN;\n const s = sortedCopy(xs);\n const rank = Math.max(1, Math.ceil(q * s.length));\n return s[rank - 1] as number;\n}\n\n/**\n * `P(X <= k)` for `X ~ Binomial(n, p)`, summed in log space so it stays finite for large `n`, for\n * `0 < p < 1` (every caller's range). A negative `k` sums nothing and is 0; a `k` past `n` sums all\n * of it and is 1.\n *\n * @internal\n */\nexport function binomialCdf(k: number, n: number, p: number): number {\n const logP = Math.log(p);\n const logQ = Math.log1p(-p);\n let logCoef = 0;\n let total = 0;\n for (let i = 0; i <= Math.min(k, n); i++) {\n if (i > 0) logCoef += Math.log(n - i + 1) - Math.log(i);\n total += Math.exp(logCoef + i * logP + (n - i) * logQ);\n }\n return Math.min(1, total);\n}\n\n/**\n * The sign test's rank for an interval on the median of `n` values: the largest `k` such that the\n * `k`-th smallest value lies below the true median with probability at most `alpha`, that is\n * `P(Binomial(n, 1/2) <= k - 1) <= alpha`. `0` when no rank qualifies (too few values).\n *\n * @internal\n */\nexport function signTestRank(n: number, alpha: number): number {\n let k = 0;\n while (k < n && binomialCdf(k, n, 0.5) <= alpha) k++;\n return k;\n}\n\n/** An interval on a median, from the sign test. */\nexport interface MedianInterval {\n /** The `rank`-th smallest value. */\n readonly low: number;\n /** The `rank`-th largest value. */\n readonly high: number;\n /** Which order statistics bound it. */\n readonly rank: number;\n /** The chance that each end alone misses the median, exactly: `P(Binomial(n, 1/2) <= rank - 1)`. */\n readonly tail: number;\n}\n\n/**\n * The distribution-free interval on the median of independent values: the `k`-th smallest and the\n * `k`-th largest, with `k` from {@link signTestRank}. It assumes nothing about the shape of the\n * noise, which on a shared runner is one-sided and heavy-tailed. `null` when there are too few\n * values for any rank to meet `alpha`.\n *\n * @internal\n */\nexport function signTestInterval(xs: readonly number[], alpha: number): MedianInterval | null {\n const rank = signTestRank(xs.length, alpha);\n if (rank === 0) return null;\n const s = sortedCopy(xs);\n // `rank` is at least 1 and at most `n`, so both order statistics exist.\n return {\n low: s[rank - 1] as number,\n high: s[s.length - rank] as number,\n rank,\n tail: binomialCdf(rank - 1, xs.length, 0.5),\n };\n}\n\n/**\n * The exact (Clopper-Pearson) one-sided upper confidence bound on a rate, from `k` events in `n`\n * trials: the largest rate `p` at which seeing `k` or fewer is still at least `1 - confidence`\n * likely. With no events this is `1 - (1 - confidence)^(1/n)`, about `3 / n` at 95%.\n *\n * @internal\n */\nexport function rateUpperBound(k: number, n: number, confidence: number): number {\n // No trials say nothing. Every trial an event bisects to 1 on its own.\n if (n === 0) return 1;\n const alpha = 1 - confidence;\n let lo = k / n;\n let hi = 1;\n // Stryker disable next-line EqualityOperator: a 101st halving moves the bound by under 2^-100, below a double's resolution.\n for (let i = 0; i < 100; i++) {\n const mid = (lo + hi) / 2;\n // Stryker disable next-line EqualityOperator: `>` and `>=` differ only where the tail equals alpha exactly, which bisection over doubles does not land on.\n if (binomialCdf(k, n, mid) > alpha) lo = mid;\n else hi = mid;\n }\n return hi;\n}\n\n/**\n * The fewest trials, all without an event, whose {@link rateUpperBound} is under `rate`: how long an\n * A/A calibration has to run before a clean record can show a false alarm rate under `rate`.\n *\n * @internal\n */\nexport function trialsForZeroEvents(rate: number, confidence: number): number {\n return Math.ceil(Math.log(1 - confidence) / Math.log1p(-rate));\n}\n\n/**\n * The Theil-Sen slope: the median of the slopes between every pair of points with distinct `x`.\n * One wild point moves it little, which matters for a heap reading that a late collection can\n * spike. `NaN` with fewer than two distinct `x`.\n *\n * @internal\n */\nexport function theilSenSlope(xs: readonly number[], ys: readonly number[]): number {\n // Pairs only exist where both vectors do; a caller passes vectors of one length.\n const slopes: number[] = [];\n xs.forEach((xi, i) => {\n for (let j = i + 1; j < xs.length; j++) {\n const dx = (xs[j] as number) - xi;\n if (dx !== 0) slopes.push(((ys[j] as number) - (ys[i] as number)) / dx);\n }\n });\n return median(slopes);\n}\n\n/**\n * Round to a number of decimal places, for readable reports. The full values stay in\n * the sample vectors.\n *\n * @internal\n */\nexport function round(n: number, places = 4): number {\n const f = 10 ** places;\n return Math.round(n * f) / f;\n}\n","/**\n * Cold import time and the bytes an import loads.\n *\n * Each timed import runs in a fresh process with no compile cache, so nothing is compiled before it\n * starts. The same number of fresh processes import an empty module, interleaved with the target's,\n * so a reader can see how much of the time is the import machinery rather than the package.\n *\n * The bytes are the files Node actually loaded for the import, found by a module hook in one further\n * process that is not timed (the hook itself costs time). This is what a Node consumer loads; it is\n * not what a bundler would keep after tree shaking, which depends on what the consumer imports.\n *\n * @packageDocumentation\n */\n\nimport { readFileSync, rmSync, mkdtempSync, writeFileSync } from \"node:fs\";\nimport { registerHooks, type LoadHookSync as LoadHook } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { join, relative } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { gzipSync } from \"node:zlib\";\n\nimport { BENCH_CONTRACT } from \"./contract.js\";\nimport { BenchError, ENTRIES, runNode } from \"./spawn.js\";\nimport { median, nearestRank, round } from \"./stats.js\";\n\n/**\n * A module `load` hook that adds each `file:` module it sees to `files`, then loads it as usual.\n *\n * @internal\n */\nexport function loadRecorder(files: Set<string>): LoadHook {\n return (url, context, nextLoad) => {\n if (url.startsWith(\"file:\")) files.add(fileURLToPath(url));\n return nextLoad(url, context);\n };\n}\n\n/**\n * The cold import process's main. `argv` is `[mode, target, outFile]`: mode `time` imports the\n * target and writes `{ ms }`; mode `files` records every `file:` module loaded during the import and\n * writes `{ files }`. Returns the exit code.\n *\n * @internal\n */\nexport async function importMain(argv: readonly string[]): Promise<number> {\n if (argv.length !== 3) return 2;\n const [mode, target, outFile] = argv as [string, string, string];\n if (mode !== \"time\" && mode !== \"files\") return 2;\n const url = pathToFileURL(target).href;\n if (mode === \"time\") {\n const t0 = performance.now();\n await import(url);\n const ms = performance.now() - t0;\n writeFileSync(outFile, JSON.stringify({ ms }));\n return 0;\n }\n // Stryker disable all: this half runs only in a fresh Node process. Under the test runner an\n // import goes through Vite's loader, which Node's module hooks never see, and mutant switching\n // does not reach a child process; e2e.test.ts checks what it records in a real one.\n const files = new Set<string>();\n const hooks = registerHooks({ load: loadRecorder(files) });\n try {\n await import(url);\n } finally {\n hooks.deregister();\n }\n writeFileSync(outFile, JSON.stringify({ files: [...files] }));\n // Stryker restore all\n return 0;\n}\n\n/** One file an import loaded. */\nexport interface LoadedFile {\n /** Relative to the working directory, so no report carries a home directory. */\n readonly path: string;\n readonly bytes: number;\n /** Gzip at level 9: roughly what it costs to download. */\n readonly gzipBytes: number;\n}\n\n/** Cold import time and loaded bytes. */\nexport interface ImportCostReport {\n readonly runs: number;\n /** One per fresh process, milliseconds, in the order taken. */\n readonly coldImportMs: readonly number[];\n readonly medianMs: number;\n readonly p95Ms: number;\n /** The same for an empty module: the import machinery alone. */\n readonly emptyImportMs: readonly number[];\n readonly emptyMedianMs: number;\n readonly files: readonly LoadedFile[];\n readonly totalBytes: number;\n readonly totalGzipBytes: number;\n}\n\nasync function oneImport(\n entry: string,\n execArgv: readonly string[],\n mode: \"time\" | \"files\",\n target: string,\n dir: string,\n): Promise<unknown> {\n const out = join(dir, \"import.json\");\n rmSync(out, { force: true });\n const outcome = await runNode(entry, [mode, target, out], execArgv, 120_000);\n try {\n return JSON.parse(String(readFileSync(out)));\n } catch {\n throw new BenchError(\n `the cold import of ${relative(process.cwd(), target)} wrote no result. Its stderr ends:\\n${outcome.stderr}`,\n );\n }\n}\n\n/**\n * Measure a target's cold import time over `IMPORT_RUNS` fresh processes, an empty module's over as\n * many, interleaved, and the bytes one import loads.\n *\n * @internal\n */\nexport async function measureImportCost(\n target: string,\n entry: string = ENTRIES.importer,\n execArgv: readonly string[] = [],\n): Promise<ImportCostReport> {\n // Stryker disable next-line StringLiteral: the prefix only names the temporary directory.\n const dir = mkdtempSync(join(tmpdir(), \"cosyte-bench-import-\"));\n try {\n const empty = join(dir, \"empty.mjs\");\n // Stryker disable next-line StringLiteral: an empty file is an empty module too; the text only has to be one.\n writeFileSync(empty, \"export {};\\n\");\n const cold: number[] = [];\n const bare: number[] = [];\n for (let i = 0; i < BENCH_CONTRACT.IMPORT_RUNS; i++) {\n const order = i % 2 === 0 ? [target, empty] : [empty, target];\n for (const which of order) {\n const { ms } = (await oneImport(entry, execArgv, \"time\", which, dir)) as { ms: number };\n (which === target ? cold : bare).push(round(ms, 3));\n }\n }\n const { files } = (await oneImport(entry, execArgv, \"files\", target, dir)) as {\n files: string[];\n };\n const loaded = files\n .map((file) => {\n const bytes = readFileSync(file);\n return {\n path: relative(process.cwd(), file),\n bytes: bytes.length,\n gzipBytes: gzipSync(bytes, { level: 9 }).length,\n };\n })\n .sort((a, b) => a.path.localeCompare(b.path));\n return {\n runs: BENCH_CONTRACT.IMPORT_RUNS,\n coldImportMs: cold,\n medianMs: round(median(cold), 3),\n p95Ms: round(nearestRank(cold, 0.95), 3),\n emptyImportMs: bare,\n emptyMedianMs: round(median(bare), 3),\n files: loaded,\n totalBytes: loaded.reduce((n, f) => n + f.bytes, 0),\n totalGzipBytes: loaded.reduce((n, f) => n + f.gzipBytes, 0),\n };\n } finally {\n rmSync(dir, { recursive: true });\n }\n}\n","/**\n * How a package describes its benchmarks.\n *\n * A suite is a module whose default export is {@link defineSuite}'s result. It is handed the module\n * under test (`bind`) rather than importing it, so one suite file measures the base build and the\n * head build of a comparison. Every corpus is built in code (`build`): the runner never takes a data\n * file, which is how its inputs stay synthetic by construction.\n *\n * @packageDocumentation\n */\n\n/** One corpus: the inputs one pass runs over, built outside every timed region. */\nexport interface BenchCorpus<TInput> {\n /** The inputs. One pass calls the measured function once on each. */\n readonly inputs: readonly TInput[];\n /** Bytes one pass handles, when it means something. Turns operations a second into bytes a second. */\n readonly bytes?: number;\n /** Called once the process has finished with this corpus, for example to remove a temporary directory. */\n readonly teardown?: () => void;\n}\n\n/** One input size of a benchmark: small, large, or anything between. */\nexport interface BenchSize<TInput> {\n /** How a reader names this size, for example `\"1 KiB\"`. Unique within its benchmark. */\n readonly label: string;\n /** Build the corpus. Called once per process, before anything is timed. */\n readonly build: () => BenchCorpus<TInput>;\n /**\n * Whether the base against head comparison runs this size. Defaults to `true`. Set `false` for a\n * size whose processes are too slow for a pull request's time budget; a reading still measures it.\n */\n readonly compare?: boolean;\n}\n\n/** One benchmark: a function measured at one or more input sizes. */\nexport interface Benchmark<TTarget, TInput, TResult> {\n /** Unique within the suite. */\n readonly name: string;\n /** The sizes, smallest first. Each size is measured on its own. */\n readonly sizes: readonly BenchSize<TInput>[];\n /** Take the imported module under test and return the function to measure. */\n readonly bind: (target: TTarget) => (input: TInput) => TResult;\n /**\n * Reduce a result to a number summed into a sink the runner checks, so the compiler cannot delete\n * the measured call. Defaults to 1 for each result that is not `null` or `undefined`; supply it\n * when the function returns nothing. The sum must grow over a measurement, so return a positive\n * number for at least some results; a run whose sink did not grow is refused.\n */\n readonly weigh?: (result: TResult) => number;\n /** The size label the long run (is the heap flat?) uses. Defaults to the first size. */\n readonly longRun?: string;\n}\n\n/** A benchmark with its input and result types erased, as a suite holds it. */\nexport type AnyBenchmark<TTarget> = Benchmark<TTarget, unknown, unknown>;\n\n/** A suite: the benchmarks of one package. */\nexport interface BenchSuite<TTarget> {\n /** Shown in every report, for example `\"@cosyte/script-utils phi-scan\"`. */\n readonly name: string;\n /** At least one. */\n readonly benchmarks: readonly AnyBenchmark<TTarget>[];\n}\n\n/**\n * Type one benchmark. Only a type helper: it returns its argument, with the input and result types\n * erased so benchmarks of different shapes can sit in one suite.\n *\n * @example\n * ```ts\n * import { defineBenchmark } from \"@cosyte/bench\";\n *\n * const b = defineBenchmark({\n * name: \"split\",\n * sizes: [{ label: \"1 KiB\", build: () => ({ inputs: [\"a|b\".repeat(341)] }) }],\n * bind: () => (s: string) => s.split(\"|\"),\n * });\n * b.name; // => \"split\"\n * ```\n */\nexport function defineBenchmark<TTarget, TInput, TResult>(\n benchmark: Benchmark<TTarget, TInput, TResult>,\n): AnyBenchmark<TTarget> {\n return benchmark as unknown as AnyBenchmark<TTarget>;\n}\n\n/**\n * Check a suite and freeze it. Throws a `TypeError` naming the problem: an empty name, no\n * benchmarks, a repeated name or label, a benchmark with no sizes, or a `longRun` naming no size.\n *\n * @example\n * ```ts\n * import { defineBenchmark, defineSuite } from \"@cosyte/bench\";\n *\n * export default defineSuite({\n * name: \"example\",\n * benchmarks: [\n * defineBenchmark({\n * name: \"split\",\n * sizes: [{ label: \"1 KiB\", build: () => ({ inputs: [\"a|b\".repeat(341)] }) }],\n * bind: () => (s: string) => s.split(\"|\"),\n * }),\n * ],\n * });\n * ```\n */\nexport function defineSuite<TTarget>(suite: BenchSuite<TTarget>): BenchSuite<TTarget> {\n return checkSuite(suite);\n}\n\nfunction fail(message: string): never {\n throw new TypeError(`@cosyte/bench: ${message}`);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction checkName(value: unknown, what: string): string {\n if (typeof value !== \"string\" || value.trim() === \"\") fail(`${what} must be a non-empty string`);\n return value;\n}\n\n/**\n * Check that a value is a suite, as a suite module's default export must be. The messages name\n * benchmarks and sizes, never an input.\n *\n * @internal\n */\nexport function checkSuite(value: unknown): BenchSuite<unknown> {\n if (!isRecord(value)) fail(\"a suite must be an object made by defineSuite\");\n const name = checkName(value[\"name\"], \"the suite name\");\n const benchmarks = value[\"benchmarks\"];\n if (!Array.isArray(benchmarks) || benchmarks.length === 0) {\n fail(`suite \"${name}\" must have at least one benchmark`);\n }\n const seen = new Set<string>();\n for (const b of benchmarks as unknown[]) {\n if (!isRecord(b)) fail(`suite \"${name}\" holds a benchmark that is not an object`);\n const bName = checkName(b[\"name\"], `a benchmark name in suite \"${name}\"`);\n if (seen.has(bName)) fail(`suite \"${name}\" has two benchmarks named \"${bName}\"`);\n seen.add(bName);\n if (typeof b[\"bind\"] !== \"function\") fail(`benchmark \"${bName}\" has no bind function`);\n if (b[\"weigh\"] !== undefined && typeof b[\"weigh\"] !== \"function\") {\n fail(`benchmark \"${bName}\" has a weigh that is not a function`);\n }\n const sizes = b[\"sizes\"];\n if (!Array.isArray(sizes) || sizes.length === 0) fail(`benchmark \"${bName}\" has no sizes`);\n const labels = new Set<string>();\n for (const s of sizes as unknown[]) {\n if (!isRecord(s)) fail(`benchmark \"${bName}\" holds a size that is not an object`);\n const label = checkName(s[\"label\"], `a size label in benchmark \"${bName}\"`);\n if (labels.has(label)) fail(`benchmark \"${bName}\" has two sizes labelled \"${label}\"`);\n labels.add(label);\n if (typeof s[\"build\"] !== \"function\")\n fail(`size \"${label}\" of \"${bName}\" has no build function`);\n if (s[\"compare\"] !== undefined && typeof s[\"compare\"] !== \"boolean\") {\n fail(`size \"${label}\" of \"${bName}\" has a compare that is not true or false`);\n }\n }\n if (b[\"longRun\"] !== undefined && !labels.has(b[\"longRun\"] as string)) {\n fail(`benchmark \"${bName}\" names a longRun size it does not have`);\n }\n }\n return Object.freeze(value) as unknown as BenchSuite<unknown>;\n}\n\n/** One case: a benchmark at one size. */\nexport interface CaseRef {\n readonly benchmark: string;\n readonly size: string;\n}\n\n/**\n * Every case in a suite, in suite order, optionally kept to the ones `only` names. A name in\n * `only` matches a whole benchmark (`\"scan\"`) or one case (`\"scan @ 1 KiB\"`). A name that matches\n * nothing throws, so a typo cannot quietly measure less than was asked. With `forComparison`, a\n * size marked `compare: false` is left out.\n *\n * @internal\n */\nexport function listCases(\n suite: BenchSuite<unknown>,\n only: readonly string[] = [],\n forComparison = false,\n): CaseRef[] {\n const all: CaseRef[] = [];\n for (const b of suite.benchmarks) {\n for (const s of b.sizes) {\n if (!forComparison || s.compare !== false) all.push({ benchmark: b.name, size: s.label });\n }\n }\n if (only.length === 0) return all;\n for (const o of only) {\n if (!all.some((c) => c.benchmark === o || caseId(c) === o)) {\n fail(`--only \"${o}\" names no benchmark or case in suite \"${suite.name}\"`);\n }\n }\n return all.filter((c) => only.includes(c.benchmark) || only.includes(caseId(c)));\n}\n\n/**\n * How a case is named in reports and in `--only`: `benchmark @ size`.\n *\n * @internal\n */\nexport function caseId(c: CaseRef): string {\n return `${c.benchmark} @ ${c.size}`;\n}\n\n/**\n * Find a case's benchmark and size in a suite. Throws when either is missing.\n *\n * @internal\n */\nexport function findCase(\n suite: BenchSuite<unknown>,\n c: CaseRef,\n): { benchmark: AnyBenchmark<unknown>; size: BenchSize<unknown> } {\n const benchmark = suite.benchmarks.find((b) => b.name === c.benchmark);\n const size = benchmark?.sizes.find((s) => s.label === c.size);\n // No benchmark means no size either, so one check covers both.\n if (size === undefined) fail(`suite \"${suite.name}\" has no case \"${caseId(c)}\"`);\n return { benchmark: benchmark as AnyBenchmark<unknown>, size };\n}\n","/**\n * The base against head comparison, and its calibration.\n *\n * A comparison is `ROUNDS` rounds. In each round every case runs once on the base build and once on\n * the head build, each in a fresh process, back to back; even rounds run the base first, odd rounds\n * the head. A drift in the machine over the run lands on both sides of a round, seconds apart, and\n * cancels in their ratio; an order effect lands on the head in half the rounds and on the base in\n * the other half, so it widens the spread of the ratios instead of biasing their median.\n *\n * Each round gives one ratio per case, `head / base` of the two processes' fastest samples. The\n * fastest, not the median, because the noise on a shared machine is one-sided (another tenant only\n * ever slows a sample down), and ADR 0001 section 1 measured `min` as the one estimator that keeps a\n * stall on one side out of a ratio. The verdict reads the sign test's interval on the median of the\n * per-round ratios, which assumes nothing about the shape of the noise, only that rounds are\n * independent.\n *\n * @packageDocumentation\n */\n\nimport type { Job, JobResult } from \"./child.js\";\nimport { BENCH_CONTRACT } from \"./contract.js\";\nimport {\n median,\n rateUpperBound,\n round,\n signTestInterval,\n trialsForZeroEvents,\n type MedianInterval,\n} from \"./stats.js\";\nimport { caseId, listCases, type BenchSuite, type CaseRef } from \"./suite.js\";\n\n/** What a comparison says about one case. */\nexport type Verdict = \"regression\" | \"improvement\" | \"no-regression\" | \"inconclusive\" | \"skipped\";\n\n/**\n * Judge one case from its per-round ratios.\n *\n * - `regression`: the whole interval is above `1 + THRESHOLD`. The head is slower by more than the\n * threshold, with each end of the interval wrong at most `ALPHA` of the time.\n * - `improvement`: the whole interval is below `1 / (1 + THRESHOLD)`.\n * - `no-regression`: the whole interval is at or below `1 + THRESHOLD`: a slowdown larger than\n * the threshold is ruled out.\n * - `inconclusive`: the interval straddles `1 + THRESHOLD`, or there are too few rounds for one.\n * Not a pass and not a failure: the rounds disagreed too much to tell.\n *\n * @example\n * ```ts\n * import { judge } from \"@cosyte/bench\";\n *\n * judge([1.1, 1.12, 1.09, 1.11, 1.1, 1.13, 1.1, 1.08, 1.12, 1.1, 1.11, 1.09]).verdict; // => \"regression\"\n * judge([1, 1.01, 0.99, 1, 1.02, 0.98, 1, 1.01, 0.99, 1, 1, 1.01]).verdict; // => \"no-regression\"\n * ```\n */\nexport function judge(\n ratios: readonly number[],\n threshold: number = BENCH_CONTRACT.THRESHOLD,\n alpha: number = BENCH_CONTRACT.ALPHA,\n): { verdict: Exclude<Verdict, \"skipped\">; interval: MedianInterval | null; medianRatio: number } {\n const interval = signTestInterval(ratios, alpha);\n const medianRatio = median(ratios);\n if (interval === null) return { verdict: \"inconclusive\", interval, medianRatio };\n const up = 1 + threshold;\n let verdict: Exclude<Verdict, \"skipped\">;\n if (interval.low > up) verdict = \"regression\";\n else if (interval.high < 1 / up) verdict = \"improvement\";\n else if (interval.high <= up) verdict = \"no-regression\";\n else verdict = \"inconclusive\";\n return { verdict, interval, medianRatio };\n}\n\n/** One case of a comparison. */\nexport interface CaseComparison extends CaseRef {\n /** Each round's base process: the fastest of its samples, milliseconds per operation. */\n readonly baseMsPerOp: readonly number[];\n /** Each round's head process: the fastest of its samples, milliseconds per operation. */\n readonly headMsPerOp: readonly number[];\n /** Each round's base samples, whole, so another estimator can be judged on the same runs. */\n readonly baseSamples: readonly (readonly number[])[];\n /** Each round's head samples, whole. */\n readonly headSamples: readonly (readonly number[])[];\n /** Each round's `head / base`. */\n readonly ratios: readonly number[];\n readonly medianRatio: number | null;\n readonly interval: MedianInterval | null;\n readonly verdict: Verdict;\n /** Why the case was skipped, when it was. A skip is not a pass. */\n readonly skipReason: string | null;\n}\n\n/** A whole comparison. */\nexport interface ComparisonBody {\n readonly rounds: number;\n readonly threshold: number;\n readonly alpha: number;\n /** The slowdown injected on the head side, for calibration. Zero in a real comparison. */\n readonly inject: number;\n readonly cases: readonly CaseComparison[];\n}\n\n/**\n * How the comparison runs one job. The real one starts a fresh process.\n *\n * @internal\n */\nexport type JobRunner = (job: Job) => Promise<JobResult>;\n\n/** What {@link compareBuilds} needs. */\nexport interface CompareOptions {\n /** The suite file, an absolute path. */\n readonly suiteFile: string;\n /** The suite, already loaded from `suiteFile`, to list its cases. */\n readonly suite: BenchSuite<unknown>;\n /** The base build's entry, an absolute path. */\n readonly base: string;\n /** The head build's entry, an absolute path. */\n readonly head: string;\n /** Keep to these benchmarks or cases. */\n readonly only?: readonly string[];\n /** A known slowdown on the head side, for calibration only. */\n readonly inject?: number;\n /** Progress lines, for a person watching. */\n readonly onProgress?: (line: string) => void;\n /** Runs one measuring job: `runInChild` for real. */\n readonly runJob: JobRunner;\n}\n\n/**\n * Compare a base build against a head build, interleaved, `ROUNDS` rounds.\n *\n * @internal\n */\nexport async function compareBuilds(options: CompareOptions): Promise<ComparisonBody> {\n const runJob = options.runJob;\n const inject = options.inject ?? 0;\n const cases = listCases(options.suite, options.only, true);\n const state = cases.map((c) => ({\n c,\n rounds: [] as { base: readonly number[]; head: readonly number[] }[],\n skip: null as string | null,\n }));\n for (let r = 0; r < BENCH_CONTRACT.ROUNDS; r++) {\n for (const s of state) {\n if (s.skip !== null) continue;\n const sides: (\"base\" | \"head\")[] = r % 2 === 0 ? [\"base\", \"head\"] : [\"head\", \"base\"];\n const got = new Map<\"base\" | \"head\", readonly number[]>();\n for (const side of sides) {\n const result = await runJob({\n mode: \"timing\",\n suite: options.suiteFile,\n target: side === \"base\" ? options.base : options.head,\n case: s.c,\n latency: false,\n inject: side === \"head\" ? inject : 0,\n });\n if (result.mode !== \"timing\")\n throw new Error(\"@cosyte/bench: a timing job returned another kind\");\n if (result.status === \"skipped\") {\n s.skip = `${side}: ${result.reason}`;\n break;\n }\n got.set(side, result.samplesMsPerOp);\n }\n const base = got.get(\"base\");\n const head = got.get(\"head\");\n // Both sides or neither: a round that skipped half way is not a round.\n if (base !== undefined && head !== undefined) s.rounds.push({ base, head });\n }\n options.onProgress?.(`round ${String(r + 1)} of ${String(BENCH_CONTRACT.ROUNDS)} done`);\n }\n return {\n rounds: BENCH_CONTRACT.ROUNDS,\n threshold: BENCH_CONTRACT.THRESHOLD,\n alpha: BENCH_CONTRACT.ALPHA,\n inject,\n cases: state.map(({ c, rounds, skip }) => {\n const recorded = {\n baseMsPerOp: rounds.map((p) => Math.min(...p.base)),\n headMsPerOp: rounds.map((p) => Math.min(...p.head)),\n baseSamples: rounds.map((p) => p.base),\n headSamples: rounds.map((p) => p.head),\n };\n if (skip !== null) {\n return {\n ...c,\n ...recorded,\n ratios: [],\n medianRatio: null,\n interval: null,\n verdict: \"skipped\",\n skipReason: skip,\n };\n }\n const ratios = rounds.map((p) => round(Math.min(...p.head) / Math.min(...p.base), 6));\n const j = judge(ratios);\n return {\n ...c,\n ...recorded,\n ratios,\n medianRatio: round(j.medianRatio, 6),\n interval: j.interval,\n verdict: j.verdict,\n skipReason: null,\n };\n }),\n };\n}\n\n/**\n * The exit code a comparison earns: 1 when any case is a regression, else 2 when any case was\n * skipped (it could not be measured), else 0.\n *\n * @internal\n */\nexport function comparisonExitCode(body: ComparisonBody): number {\n if (body.cases.some((c) => c.verdict === \"regression\")) return 1;\n if (body.cases.some((c) => c.verdict === \"skipped\")) return 2;\n return 0;\n}\n\n/** A rate with its exact upper bound. */\nexport interface CountedRate {\n readonly events: number;\n readonly trials: number;\n readonly rate: number;\n /** The one-sided upper bound at `REQUIRED_CONFIDENCE` (Clopper-Pearson). */\n readonly upperBound: number;\n}\n\nfunction counted(events: number, trials: number): CountedRate {\n return {\n events,\n trials,\n rate: trials === 0 ? 0 : round(events / trials, 6),\n upperBound: round(rateUpperBound(events, trials, BENCH_CONTRACT.REQUIRED_CONFIDENCE), 6),\n };\n}\n\n/** The ratio one case was observed at over a whole calibration. */\nexport interface ObservedRatio extends CaseRef {\n /** Measured rounds, pooled over every comparison that measured the case. */\n readonly rounds: number;\n /**\n * The median of those rounds' `head / base` ratios, or `null` when no round measured. Under an\n * injected slowdown this is the slowdown the head side was actually measured at, which is not\n * `1 + inject` (see `sampleThroughput`): a detection rate is read against it.\n */\n readonly medianRatio: number | null;\n}\n\n/** A calibration: many comparisons of known outcome. */\nexport interface CalibrationBody {\n /** The slowdown injected on the head side. Zero is an A/A calibration: every regression is a false alarm. */\n readonly inject: number;\n readonly comparisons: number;\n /** Each comparison's cases, kept whole so a different rule can be judged against the same runs. */\n readonly runs: readonly (readonly CaseComparison[])[];\n /** Case verdicts of `regression`, out of the case verdicts that measured. A skipped case is not a trial. */\n readonly perCase: CountedRate;\n /**\n * Comparisons with at least one `regression`, out of the comparisons whose outcome is known: every\n * case measured, or a regression was called. A comparison that skipped a case and called no\n * regression is neither a pass nor a trial.\n */\n readonly perComparison: CountedRate;\n /** Comparisons with at least one skipped case, out of all comparisons. A required check is red on each (exit 2). */\n readonly skippedComparisons: CountedRate;\n /** Case verdicts by kind. */\n readonly verdicts: Readonly<Record<Verdict, number>>;\n /** Each case's observed ratio, in the order the cases first appear. */\n readonly observed: readonly ObservedRatio[];\n /** For an A/A calibration: whether the timing comparison may now be a required check, and why. */\n readonly requiredRule: {\n readonly applies: boolean;\n readonly met: boolean;\n readonly reason: string;\n };\n}\n\n/**\n * Summarize calibration runs. With `inject` zero, every `regression` is a false alarm, and the rule\n * for making the comparison a required check is judged. A required check on an unchanged pull\n * request is wrongly red for either of two reasons, so the rule bounds both at\n * `REQUIRED_CONFIDENCE`: the per-comparison false alarm rate (over the comparisons whose outcome is\n * known) and the rate of comparisons that skipped a case (over all of them) must each have an upper\n * bound under `REQUIRED_FALSE_ALARM_RATE`. Comparisons that measured nothing count toward neither a\n * pass nor a trial, so they can never meet it. With `inject` above zero every `regression` is a\n * detection, and the rule does not apply.\n *\n * @internal\n */\nexport function summarizeCalibration(\n inject: number,\n runs: readonly (readonly CaseComparison[])[],\n): CalibrationBody {\n const verdicts: Record<Verdict, number> = {\n regression: 0,\n improvement: 0,\n \"no-regression\": 0,\n inconclusive: 0,\n skipped: 0,\n };\n const pooled = new Map<string, { ref: CaseRef; ratios: number[] }>();\n let caseTrials = 0;\n let caseEvents = 0;\n let compTrials = 0;\n let compEvents = 0;\n let compSkipped = 0;\n for (const run of runs) {\n let alarmed = false;\n let skipped = false;\n for (const c of run) {\n verdicts[c.verdict]++;\n const id = caseId(c);\n const pool = pooled.get(id) ?? { ref: { benchmark: c.benchmark, size: c.size }, ratios: [] };\n pooled.set(id, pool);\n if (c.verdict === \"skipped\") {\n skipped = true;\n continue;\n }\n pool.ratios.push(...c.ratios);\n caseTrials++;\n if (c.verdict === \"regression\") {\n caseEvents++;\n alarmed = true;\n }\n }\n if (skipped) compSkipped++;\n if (alarmed || !skipped) compTrials++;\n if (alarmed) compEvents++;\n }\n const perComparison = counted(compEvents, compTrials);\n const skippedComparisons = counted(compSkipped, runs.length);\n const line = BENCH_CONTRACT.REQUIRED_FALSE_ALARM_RATE;\n const needed = trialsForZeroEvents(line, BENCH_CONTRACT.REQUIRED_CONFIDENCE);\n // Four decimals of a percentage: a bound of 0.9969% must not print as \"1%\" beside \"under 1%\".\n const pct = (x: number) => `${String(round(x * 100, 4))}%`;\n // Stryker disable next-line EqualityOperator: an exact Clopper-Pearson bound of exactly 1% is not reached by any whole count of comparisons.\n const alarmsUnder = perComparison.upperBound < line;\n // Stryker disable next-line EqualityOperator: the same bound, on the same whole counts.\n const skipsUnder = skippedComparisons.upperBound < line;\n const alarms = `${String(compEvents)} false alarm(s) in ${String(compTrials)} A/A comparisons that measured every case or called a regression`;\n const skips = `${String(compSkipped)} of ${String(runs.length)} comparisons skipped a case`;\n let requiredRule: CalibrationBody[\"requiredRule\"];\n if (inject !== 0) {\n requiredRule = {\n applies: false,\n met: false,\n reason: \"a calibration with an injected slowdown measures detection, not false alarms\",\n };\n } else if (alarmsUnder && skipsUnder) {\n requiredRule = {\n applies: true,\n met: true,\n reason: `${alarms}, and ${skips}: both rates are under ${pct(line)} with ${pct(BENCH_CONTRACT.REQUIRED_CONFIDENCE)} confidence (upper bounds ${pct(perComparison.upperBound)} and ${pct(skippedComparisons.upperBound)})`,\n };\n } else {\n const why: string[] = [];\n if (!alarmsUnder) {\n why.push(\n `${alarms}: the upper bound ${pct(perComparison.upperBound)} is not under ${pct(line)}, and a clean record needs at least ${String(needed)} of them`,\n );\n }\n if (!skipsUnder) {\n why.push(\n `${skips}, and a required check is red on each: the upper bound ${pct(skippedComparisons.upperBound)} on that rate is not under ${pct(line)}`,\n );\n }\n requiredRule = { applies: true, met: false, reason: why.join(\"; \") };\n }\n return {\n inject,\n comparisons: runs.length,\n runs,\n perCase: counted(caseEvents, caseTrials),\n perComparison,\n skippedComparisons,\n verdicts,\n observed: [...pooled.values()].map(({ ref, ratios }) => ({\n ...ref,\n rounds: ratios.length,\n medianRatio: ratios.length === 0 ? null : round(median(ratios), 6),\n })),\n requiredRule,\n };\n}\n\n/** What {@link calibrateComparison} needs: a comparison's options and how many to run. */\nexport interface CalibrateOptions extends CompareOptions {\n readonly comparisons: number;\n}\n\n/**\n * Run `comparisons` full comparisons and summarize them. Base and head should be the same build (two\n * copies, ideally in two directories, so a difference in where the code sits is part of what is\n * calibrated); `inject` makes the head side slower by a known fraction.\n *\n * @internal\n */\nexport async function calibrateComparison(options: CalibrateOptions): Promise<CalibrationBody> {\n const runs: CaseComparison[][] = [];\n for (let k = 0; k < options.comparisons; k++) {\n const { onProgress: _quiet, ...quiet } = options;\n const body = await compareBuilds(quiet);\n runs.push([...body.cases]);\n const alarms = body.cases.filter((c) => c.verdict === \"regression\").map(caseId);\n options.onProgress?.(\n `comparison ${String(k + 1)} of ${String(options.comparisons)}: ` +\n (alarms.length === 0 ? \"no regression verdict\" : `regression on ${alarms.join(\", \")}`),\n );\n }\n return summarizeCalibration(options.inject ?? 0, runs);\n}\n","/**\n * A reading: how fast, how much memory and how heavy one build is, on this machine.\n *\n * A reading is not a guarantee and travels with its machine: it is what the results repository keeps\n * over time, compared only within one runner class.\n *\n * @packageDocumentation\n */\n\nimport type { JobResult, MemoryResult, TimingResult } from \"./child.js\";\nimport type { JobRunner } from \"./compare.js\";\nimport type { ImportCostReport } from \"./import-cost.js\";\nimport type { LatencyReport } from \"./measure.js\";\nimport type { AllocationReport, LongRunReport, PeakReport } from \"./memory.js\";\nimport { median, round } from \"./stats.js\";\nimport { findCase, listCases, type BenchSize, type BenchSuite, type CaseRef } from \"./suite.js\";\n\n/** Throughput of one case. */\nexport type Throughput =\n | {\n readonly status: \"measured\";\n /** One entry per process: its samples and their median, milliseconds per operation. */\n readonly processes: readonly {\n readonly samplesMsPerOp: readonly number[];\n readonly medianMsPerOp: number;\n }[];\n /** The median of the process medians. */\n readonly medianMsPerOp: number;\n readonly opsPerSecond: number;\n /** `null` when the suite gave no byte count for the corpus. */\n readonly bytesPerSecond: number | null;\n }\n | { readonly status: \"skipped\"; readonly reason: string };\n\n/** Everything a reading measured for one case. */\nexport interface CaseReading extends CaseRef {\n readonly inputsPerPass: number;\n readonly bytesPerPass: number | null;\n readonly throughput: Throughput;\n readonly latency: LatencyReport | null;\n readonly allocations: AllocationReport | null;\n readonly peak: PeakReport | null;\n readonly longRun: LongRunReport | null;\n}\n\n/** A whole reading. */\nexport interface ReadingBody {\n /** Fresh processes timed per case. */\n readonly processes: number;\n readonly cases: readonly CaseReading[];\n /** `null` when import cost was not asked for. */\n readonly importCost: ImportCostReport | null;\n}\n\n/** What {@link readBuild} needs. */\nexport interface ReadOptions {\n readonly suiteFile: string;\n readonly suite: BenchSuite<unknown>;\n /** The build's entry, an absolute path. */\n readonly target: string;\n readonly only?: readonly string[];\n /** Fresh timing processes per case. At least 1. */\n readonly processes?: number;\n /** Measure memory (two more processes per case). */\n readonly memory?: boolean;\n /** Measure cold import time and loaded bytes. */\n readonly importCost?: boolean;\n readonly onProgress?: (line: string) => void;\n /** Runs one measuring job: `runInChild` for real. */\n readonly runJob: JobRunner;\n /** Measures cold import cost: `measureImportCost` for real. */\n readonly measureImport: (target: string) => Promise<ImportCostReport>;\n}\n\nfunction expectTiming(result: JobResult): TimingResult {\n if (result.mode !== \"timing\")\n throw new Error(\"@cosyte/bench: a timing job returned another kind\");\n return result;\n}\n\nfunction expectMemory(result: JobResult): MemoryResult {\n if (result.mode === \"timing\")\n throw new Error(\"@cosyte/bench: a memory job returned a timing result\");\n return result;\n}\n\ntype Measured = Extract<TimingResult, { status: \"measured\" }>;\n\n/**\n * Pool one case's timing processes: the median of their medians, or the first skip.\n *\n * @internal\n */\nexport function summarizeThroughput(\n first: TimingResult,\n rest: readonly TimingResult[],\n): Throughput {\n const measured: Measured[] = [];\n for (const t of [first, ...rest]) {\n if (t.status === \"skipped\") return { status: \"skipped\", reason: t.reason };\n measured.push(t);\n }\n const per = measured.map((t) => ({\n samplesMsPerOp: t.samplesMsPerOp,\n medianMsPerOp: t.medianMsPerOp,\n }));\n const mid = median(per.map((x) => x.medianMsPerOp));\n const perOpBytes = first.bytesPerPass === null ? null : first.bytesPerPass / first.inputsPerPass;\n return {\n status: \"measured\",\n processes: per,\n medianMsPerOp: mid,\n opsPerSecond: round(1000 / mid, 2),\n bytesPerSecond: perOpBytes === null ? null : round(perOpBytes * (1000 / mid), 0),\n };\n}\n\n/**\n * Take a reading of one build: per case, throughput from `processes` fresh processes (latency from\n * the first), allocations from one more, peak heap and (for the benchmark's long-run size) the long\n * run from another; then the build's cold import cost.\n *\n * @internal\n */\nexport async function readBuild(options: ReadOptions): Promise<ReadingBody> {\n const runJob = options.runJob;\n const processes = options.processes ?? 3;\n if (!Number.isInteger(processes) || processes < 1) {\n throw new TypeError(\"@cosyte/bench: processes must be a positive integer\");\n }\n const base = { suite: options.suiteFile, target: options.target };\n const cases: CaseReading[] = [];\n for (const c of listCases(options.suite, options.only)) {\n const timing = async (latency: boolean) =>\n expectTiming(await runJob({ mode: \"timing\", ...base, case: c, latency, inject: 0 }));\n const first = await timing(true);\n const rest: TimingResult[] = [];\n for (let p = 1; p < processes; p++) rest.push(await timing(false));\n const throughput = summarizeThroughput(first, rest);\n const latency = first.status === \"measured\" ? first.latency : null;\n let allocations: AllocationReport | null = null;\n let peak: PeakReport | null = null;\n let longRun: LongRunReport | null = null;\n if (options.memory ?? true) {\n allocations = expectMemory(await runJob({ mode: \"alloc\", ...base, case: c })).allocations;\n const { benchmark } = findCase(options.suite, c);\n // A suite has at least one size per benchmark (checkSuite), so the first one exists.\n const longRunSize = benchmark.longRun ?? (benchmark.sizes[0] as BenchSize<unknown>).label;\n const heap = expectMemory(\n await runJob({ mode: \"heap\", ...base, case: c, longRun: c.size === longRunSize }),\n );\n peak = heap.peak;\n longRun = heap.longRun;\n }\n cases.push({\n ...c,\n inputsPerPass: first.inputsPerPass,\n bytesPerPass: first.bytesPerPass,\n throughput,\n latency,\n allocations,\n peak,\n longRun,\n });\n options.onProgress?.(`read ${c.benchmark} @ ${c.size}`);\n }\n const importCost =\n (options.importCost ?? true) ? await options.measureImport(options.target) : null;\n return { processes, cases, importCost };\n}\n","/**\n * Markdown for a person: a pull request comment, a job summary, a terminal. The JSON document is the\n * record; this is its reading.\n *\n * @packageDocumentation\n */\n\nimport type { CaseComparison } from \"./compare.js\";\nimport type { ResultsDocument } from \"./results.js\";\nimport { round } from \"./stats.js\";\n\nfunction pct(x: number): string {\n const v = round(x * 100, 1);\n return `${v > 0 ? \"+\" : \"\"}${String(v)}%`;\n}\n\nfunction bytes(n: number): string {\n if (Math.abs(n) >= 1024 * 1024) return `${String(round(n / (1024 * 1024), 2))} MiB`;\n if (Math.abs(n) >= 1024) return `${String(round(n / 1024, 1))} KiB`;\n return `${String(round(n, 1))} B`;\n}\n\nfunction share(x: number): string {\n return `${String(round(x * 100, 2))}%`;\n}\n\nfunction time(ms: number): string {\n if (ms >= 1) return `${String(round(ms, 3))} ms`;\n if (ms >= 0.001) return `${String(round(ms * 1000, 2))} us`;\n return `${String(round(ms * 1e6, 1))} ns`;\n}\n\nfunction ns(n: number | null): string {\n return n === null ? \"n/a\" : time(n / 1e6);\n}\n\nfunction header(doc: ResultsDocument, title: string): string[] {\n const e = doc.environment;\n return [\n `### ${title}: ${doc.suite.name}`,\n \"\",\n `Node ${e.node} on ${e.runner.class} (${e.cpuModel ?? \"unknown CPU\"}, ${String(e.logicalCpus)} logical CPUs), @cosyte/bench ${doc.tool.version}, ${doc.createdAt}.`,\n \"\",\n ];\n}\n\nfunction comparisonRow(c: CaseComparison): string {\n const base =\n c.baseMsPerOp.length === 0\n ? \"n/a\"\n : time(c.baseMsPerOp.reduce((a, b) => a + b, 0) / c.baseMsPerOp.length);\n const head =\n c.headMsPerOp.length === 0\n ? \"n/a\"\n : time(c.headMsPerOp.reduce((a, b) => a + b, 0) / c.headMsPerOp.length);\n const change = c.medianRatio === null ? \"n/a\" : pct(c.medianRatio - 1);\n const interval =\n c.interval === null ? \"n/a\" : `${pct(c.interval.low - 1)} to ${pct(c.interval.high - 1)}`;\n const verdict = c.verdict === \"skipped\" ? `skipped (${String(c.skipReason)})` : c.verdict;\n return `| ${c.benchmark} | ${c.size} | ${base} | ${head} | ${change} | ${interval} | ${verdict} |`;\n}\n\n/**\n * Render a results document as Markdown.\n *\n * @internal\n */\nexport function renderMarkdown(doc: ResultsDocument): string {\n const lines: string[] = [];\n if (doc.kind === \"comparison\") {\n const b = doc.comparison;\n lines.push(...header(doc, \"Base against head\"));\n lines.push(\n `${String(b.rounds)} interleaved rounds, a fresh process per side per case per round. A regression is a change whose whole interval is above ${pct(b.threshold)}; each end of the interval is wrong at most ${String(round(b.alpha * 100, 1))}% of the time. Base and head times are means of the per-round fastest samples.`,\n \"\",\n \"| Benchmark | Size | Base | Head | Change (median) | Interval | Verdict |\",\n \"| --- | --- | --- | --- | --- | --- | --- |\",\n ...b.cases.map(comparisonRow),\n );\n } else if (doc.kind === \"calibration\") {\n const c = doc.calibration;\n lines.push(\n ...header(\n doc,\n c.inject === 0 ? \"A/A calibration\" : `Calibration with a ${share(c.inject)} slowdown`,\n ),\n );\n const what = c.inject === 0 ? \"false alarms\" : \"detections\";\n lines.push(\n `${String(c.comparisons)} comparisons. Regression verdicts (${what}): ${String(c.perCase.events)} of ${String(c.perCase.trials)} measured case verdicts (${share(c.perCase.rate)}, upper bound ${share(c.perCase.upperBound)}); ${String(c.perComparison.events)} of ${String(c.perComparison.trials)} comparisons that measured every case or called a regression (${share(c.perComparison.rate)}, upper bound ${share(c.perComparison.upperBound)}). Comparisons that skipped a case: ${String(c.skippedComparisons.events)} of ${String(c.skippedComparisons.trials)} (${share(c.skippedComparisons.rate)}, upper bound ${share(c.skippedComparisons.upperBound)}).`,\n \"\",\n `Verdicts: ${Object.entries(c.verdicts)\n .map(([k, v]) => `${k} ${String(v)}`)\n .join(\", \")}.`,\n \"\",\n \"The change each case was observed at, the median of every measured round's head / base:\",\n \"\",\n \"| Benchmark | Size | Measured rounds | Observed change |\",\n \"| --- | --- | --- | --- |\",\n ...c.observed.map(\n (o) =>\n `| ${o.benchmark} | ${o.size} | ${String(o.rounds)} | ${o.medianRatio === null ? \"n/a\" : pct(o.medianRatio - 1)} |`,\n ),\n );\n if (c.requiredRule.applies) {\n lines.push(\n \"\",\n `Required check rule: ${c.requiredRule.met ? \"met\" : \"not met\"}. ${c.requiredRule.reason}.`,\n );\n }\n } else {\n const r = doc.reading;\n lines.push(...header(doc, \"Reading\"));\n lines.push(\n `Throughput is the median of ${String(r.processes)} fresh processes. Latency is per call, nearest rank. Memory: allocations per operation, the peak heap of one call above the settled heap, and whether the settled heap stays flat over a long run.`,\n \"\",\n \"| Benchmark | Size | Per op | Ops/s | Bytes/s | p50 | p95 | p99 | Alloc/op | Peak heap | Long run |\",\n \"| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\",\n );\n for (const c of r.cases) {\n const t = c.throughput;\n const perOp = t.status === \"measured\" ? time(t.medianMsPerOp) : `skipped (${t.reason})`;\n const ops = t.status === \"measured\" ? String(t.opsPerSecond) : \"n/a\";\n const bps =\n t.status === \"measured\" && t.bytesPerSecond !== null\n ? `${bytes(t.bytesPerSecond)}/s`\n : \"n/a\";\n const l = c.latency;\n const lat =\n l === null\n ? [\"n/a\", \"n/a\", \"n/a\"]\n : l.status === \"measured\"\n ? [ns(l.p50Ns), ns(l.p95Ns), ns(l.p99Ns)]\n : [`skipped (${l.reason})`, \"n/a\", \"n/a\"];\n const a = c.allocations;\n const alloc =\n a === null\n ? \"n/a\"\n : a.status === \"measured\"\n ? bytes(a.heapBytesPerOp + a.externalBytesPerOp)\n : `skipped (${a.reason})`;\n const p = c.peak;\n const peak =\n p === null\n ? \"n/a\"\n : p.status === \"measured\"\n ? bytes(p.peakHeapBytes)\n : `skipped (${p.reason})`;\n const lr = c.longRun;\n const long =\n lr === null\n ? \"\"\n : lr.status === \"measured\"\n ? `${lr.verdict} (${bytes(lr.growthBytes)} over ${String(lr.ops)} ops, ${String(lr.slopeBytesPerOp)} B/op)`\n : `skipped (${lr.reason})`;\n lines.push(\n `| ${c.benchmark} | ${c.size} | ${perOp} | ${ops} | ${bps} | ${lat.join(\" | \")} | ${alloc} | ${peak} | ${long} |`,\n );\n }\n if (r.importCost !== null) {\n const i = r.importCost;\n lines.push(\n \"\",\n `Cold import: median ${time(i.medianMs)}, p95 ${time(i.p95Ms)} over ${String(i.runs)} fresh processes (an empty module: median ${time(i.emptyMedianMs)}). Loaded: ${String(i.files.length)} file(s), ${bytes(i.totalBytes)}, ${bytes(i.totalGzipBytes)} gzipped.`,\n );\n }\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n","/**\n * The frozen measurement constants.\n *\n * Every value here is fixed by **ADR 0001: the performance measurement contract**\n * (`documentation/decisions/0001-perf-measurement-contract.md` in the `config` repo), which in turn\n * derives them from the PERF-P0 calibration: 3,200 4N-vs-N ratios on a linear workload, 320 on a\n * deliberately O(n²) one, across two runner classes on Node 22.23.1 / V8 12.4.\n *\n * They are **not tuning knobs and are deliberately not overridable per package.** The ceiling was\n * set from the worst false alarm in that population and the weakest real signal at `hl7`'s own\n * fixture size, so it is conditional on the estimator, the sampling shape *and* the warmup rule:\n * changing any one of them moves the operating point the ceiling was measured against. The ADR's\n * review triggers are the process for changing them.\n *\n * @packageDocumentation\n */\n\n/**\n * The measurement constants, frozen. See {@link PERF_CONTRACT}.\n */\nexport interface PerfContractShape {\n /**\n * Upper bound on `min(scaled) / min(base)`. **8**: above the worst false alarm in 3,200 samples\n * (6.649, `min`, container leg) and below the weakest real O(n²) signal measured at `hl7`'s own\n * fixture size (8.84). Margins 1.20× / 1.10×. Measured.\n */\n readonly RATIO_CEILING: number;\n /**\n * Lower bound on the same ratio. **1.5**: below all 3,200 samples (worst 1.702) and above the ≈1\n * that a same-workload-on-both-phases bug produces. Margin 1.13×, the thinnest in the contract.\n * Measured.\n */\n readonly RATIO_FLOOR: number;\n /**\n * Timed repetitions per phase. **5**, measured by construction: the whole calibration was taken at\n * 5 reps, and `min` over a different rep count is a different statistic.\n */\n readonly REPS: number;\n /**\n * The multiplier between the base phase and the scaled phase. **4×**, measured by construction:\n * every ratio in the dataset is a 4× step, so the ideal linear ratio is 4.\n */\n readonly SCALE_STEP: number;\n /**\n * Floor on the base phase's `min` sample, in milliseconds. **4**: the fastest base phase in all\n * 3,200 samples was 4.14 ms; below that the ceiling is extrapolation, so the gate refuses to\n * answer. Measured.\n */\n readonly MIN_PHASE_MS: number;\n /**\n * Minimum total warmup time before the stability rule may fire, in milliseconds. **500**: one\n * further P0 trial (136 to 294 ms of the same workload) brought rep-to-rep drift from as much as\n * 1.23× inside ±5%; 500 ms is 1.7 to 3.7× that. Measured.\n */\n readonly WARMUP_MIN_MS: number;\n /**\n * Minimum timed duration of one warmup batch, in milliseconds. **50**: judgement forced by\n * measurement: a single ~4 to 9 ms pass is not stable enough to satisfy ±5% three times running\n * (1 to 92% of warm phases do, by axis), and a 50 ms batch aggregates 5 to 12 passes. Aggregation is\n * what shrinks that jitter, so the batch length is load-bearing rather than a free choice.\n */\n readonly WARMUP_BATCH_MS: number;\n /**\n * Hard cap on total warmup, in milliseconds. **5 000**: judgement, no measured basis. Bounds the\n * fleet cost and leaves ~100 batches of headroom, so the cap is reached only by a genuinely\n * unsettled runtime.\n */\n readonly WARMUP_MAX_MS: number;\n /**\n * Relative tolerance for the warmup stability rule, as a fraction. **0.05** (±5%): judgement\n * anchored on P0's rep1/rep5 ratio inside a warm 5-rep phase (0.96 to 1.05× GitHub, 0.97 to 1.02×\n * container), which is a different statistic at a different granularity.\n */\n readonly WARMUP_STABLE_TOL: number;\n /**\n * How many consecutive batches must lie inside the tolerance. **3**: two consecutive can be met\n * by a coincidental pair on a heavy-tailed distribution; a third costs 50 ms against a 5 s cap.\n */\n readonly WARMUP_STABLE_BATCHES: number;\n}\n\n/**\n * The frozen measurement constants, as decided by ADR 0001.\n *\n * Read them, print them in your own diagnostics, assert against them, but do not expect a knob to\n * override them. A package that cannot satisfy the contract at its fixture sizes has a fixture-size\n * problem, and {@link assertScalingGateFires} is what turns that into a build failure.\n *\n * @example\n * ```ts\n * import { PERF_CONTRACT } from \"@cosyte/test-utils/perf\";\n *\n * PERF_CONTRACT.RATIO_CEILING; // => 8\n * PERF_CONTRACT.SCALE_STEP; // => 4\n * ```\n */\nexport const PERF_CONTRACT: PerfContractShape = Object.freeze({\n RATIO_CEILING: 8,\n RATIO_FLOOR: 1.5,\n REPS: 5,\n SCALE_STEP: 4,\n MIN_PHASE_MS: 4,\n WARMUP_MIN_MS: 500,\n WARMUP_BATCH_MS: 50,\n WARMUP_MAX_MS: 5_000,\n WARMUP_STABLE_TOL: 0.05,\n WARMUP_STABLE_BATCHES: 3,\n});\n","/**\n * The timing primitives: the warmup, the throughput samples and the latency calls. They run inside\n * a measuring process, one case per process, and take their clocks as arguments so their tests can\n * drive them with exact arithmetic instead of a machine's noise.\n *\n * @packageDocumentation\n */\n\n// The one source of the warmup rule. A relative import of the scaling gate's own contract file, not\n// of the published `@cosyte/test-utils/perf`, so the build bundles it into `dist` and this package\n// keeps no runtime dependency (that one would bring `fast-check` in as a peer). A change to the rule\n// there changes this package's build, so it needs a changeset that bumps this package too.\nimport { PERF_CONTRACT } from \"../../test-utils/src/perf/contract.js\";\nimport { BENCH_CONTRACT } from \"./contract.js\";\nimport { median, nearestRank, round } from \"./stats.js\";\n\n/**\n * The warmup rule, read from `PERF_CONTRACT` in `@cosyte/test-utils/perf` (ADR 0001 section 2) and\n * renamed, so the scaling gate and the benchmarks warm up by one rule kept in one place.\n *\n * @internal\n */\nexport const WARMUP = Object.freeze({\n MIN_MS: PERF_CONTRACT.WARMUP_MIN_MS,\n BATCH_MS: PERF_CONTRACT.WARMUP_BATCH_MS,\n MAX_MS: PERF_CONTRACT.WARMUP_MAX_MS,\n STABLE_TOL: PERF_CONTRACT.WARMUP_STABLE_TOL,\n STABLE_BATCHES: PERF_CONTRACT.WARMUP_STABLE_BATCHES,\n});\n\n/**\n * A millisecond clock. `performance.now` in a real run.\n *\n * @internal\n */\nexport type Clock = () => number;\n\n/**\n * A nanosecond clock. `process.hrtime.bigint` in a real run.\n *\n * @internal\n */\nexport type NsClock = () => bigint;\n\n/** What the warmup did. */\nexport interface WarmupReport {\n /** Whether three batches in a row came within 5% of their median before 5 s ran out. */\n readonly stable: boolean;\n /** Wall time spent warming, in milliseconds. */\n readonly elapsedMs: number;\n /** Passes over the corpus. */\n readonly passes: number;\n /** Each batch's milliseconds per pass. */\n readonly batches: readonly number[];\n}\n\n/**\n * Whether the last `STABLE_BATCHES` batches all lie within `STABLE_TOL` of their median.\n *\n * @internal\n */\nexport function batchesAreStable(batches: readonly number[]): boolean {\n if (batches.length < WARMUP.STABLE_BATCHES) return false;\n const window = batches.slice(-WARMUP.STABLE_BATCHES);\n const mid = median(window);\n // A zero median makes every relative distance `NaN`, which no tolerance accepts: refused.\n return window.every((b) => Math.abs(b - mid) / mid <= WARMUP.STABLE_TOL);\n}\n\n/**\n * Warm up by time, with a stability rule, never by a fixed count (ADR 0001 section 2): batches of\n * whole passes of at least 50 ms, at least 500 ms in all, until three batches in a row lie within\n * 5% of their median, or 5 s pass without that.\n *\n * @internal\n */\nexport function warmUp(pass: () => void, clock: Clock): WarmupReport {\n const start = clock();\n const batches: number[] = [];\n let passes = 0;\n for (;;) {\n const b0 = clock();\n let inBatch = 0;\n let batchMs: number;\n do {\n pass();\n inBatch++;\n batchMs = clock() - b0;\n } while (batchMs < WARMUP.BATCH_MS);\n passes += inBatch;\n batches.push(batchMs / inBatch);\n const elapsedMs = clock() - start;\n if (elapsedMs >= WARMUP.MIN_MS && batchesAreStable(batches)) {\n return { stable: true, elapsedMs, passes, batches };\n }\n if (elapsedMs >= WARMUP.MAX_MS) return { stable: false, elapsedMs, passes, batches };\n }\n}\n\n/**\n * Take `SAMPLES` throughput samples. A sample runs whole passes until `SAMPLE_MIN_MS` has passed\n * and reports milliseconds per operation.\n *\n * `inject` plants a slowdown, for calibration only: after each pass the loop reads the clock until\n * `inject` times that pass's own measured time has passed, then starts the next pass, so each\n * sample's time includes the spin. That is all it does. It does not make the measured code slower\n * by exactly that fraction: the spin changes the loop the engine compiles and what the processor\n * does between passes, so the ratio a comparison then measures is not `1 + inject` and differs by\n * workload and machine. A calibration reports the ratio it observed for each case\n * (`CalibrationBody.observed`), and a detection rate is read against that, never against `inject`.\n * Zero in every real measurement.\n *\n * @internal\n */\nexport function sampleThroughput(\n pass: () => void,\n opsPerPass: number,\n clock: Clock,\n inject = 0,\n): number[] {\n const samples: number[] = [];\n for (let s = 0; s < BENCH_CONTRACT.SAMPLES; s++) {\n const t0 = clock();\n let t = t0;\n let passes = 0;\n do {\n const p0 = t;\n pass();\n t = clock();\n // Zero in a real measurement, so `until` is `t` and the clock is not read again.\n const until = t + inject * (t - p0);\n while (t < until) t = clock();\n passes++;\n } while (t - t0 < BENCH_CONTRACT.SAMPLE_MIN_MS);\n samples.push((t - t0) / (passes * opsPerPass));\n }\n return samples;\n}\n\n/**\n * The median gap between two back-to-back reads of the nanosecond clock: what one latency reading\n * costs before the call itself.\n *\n * @internal\n */\nexport function timerOverheadNs(ns: NsClock, reads = 1_000): number {\n const gaps: number[] = [];\n for (let i = 0; i < reads; i++) {\n const a = ns();\n const b = ns();\n gaps.push(Number(b - a));\n }\n return median(gaps);\n}\n\n/** Per-call latency, or why there is none. */\nexport type LatencyReport =\n | {\n readonly status: \"measured\";\n readonly calls: number;\n readonly timerOverheadNs: number;\n /** `null` when fewer than `LATENCY_TAIL_CALLS` calls lie above the percentile. */\n readonly p50Ns: number | null;\n readonly p95Ns: number | null;\n readonly p99Ns: number | null;\n readonly maxNs: number;\n }\n | {\n readonly status: \"skipped\";\n readonly reason: \"latency-below-timer-resolution\";\n readonly calls: number;\n readonly timerOverheadNs: number;\n readonly p50Ns: number;\n };\n\n/**\n * A percentile, or `null` when too few calls lie above it to tell it from the maximum.\n *\n * @internal\n */\nexport function tailPercentile(times: readonly number[], q: number): number | null {\n return times.length * (1 - q) >= BENCH_CONTRACT.LATENCY_TAIL_CALLS ? nearestRank(times, q) : null;\n}\n\n/**\n * Time calls one at a time: at least `LATENCY_MIN_CALLS`, then until `LATENCY_BUDGET_MS` or\n * `LATENCY_MAX_CALLS`. Skips, loudly and typed, when the median call is under\n * `LATENCY_TIMER_MULTIPLE` clock reads: then the clock, not the call, is being measured.\n *\n * @internal\n */\nexport function measureLatency(call: (i: number) => void, ns: NsClock): LatencyReport {\n const overhead = timerOverheadNs(ns);\n const budgetNs = BigInt(BENCH_CONTRACT.LATENCY_BUDGET_MS) * 1_000_000n;\n const times: number[] = [];\n const start = ns();\n let now = start;\n while (\n times.length < BENCH_CONTRACT.LATENCY_MAX_CALLS &&\n (times.length < BENCH_CONTRACT.LATENCY_MIN_CALLS || now - start < budgetNs)\n ) {\n const a = ns();\n call(times.length);\n now = ns();\n times.push(Number(now - a));\n }\n const p50 = nearestRank(times, 0.5);\n if (p50 < BENCH_CONTRACT.LATENCY_TIMER_MULTIPLE * overhead) {\n return {\n status: \"skipped\",\n reason: \"latency-below-timer-resolution\",\n calls: times.length,\n timerOverheadNs: round(overhead, 1),\n p50Ns: p50,\n };\n }\n return {\n status: \"measured\",\n calls: times.length,\n timerOverheadNs: round(overhead, 1),\n p50Ns: tailPercentile(times, 0.5),\n p95Ns: tailPercentile(times, 0.95),\n p99Ns: tailPercentile(times, 0.99),\n maxNs: Math.max(...times),\n };\n}\n","/**\n * The results document: one JSON file per reading, comparison or calibration, in a versioned shape a\n * results repository can keep for years and read back.\n *\n * The shape is fixed by a JSON Schema ({@link RESULTS_SCHEMA}, also shipped as\n * `schema/results-v1.schema.json`). Version 1 only grows: a new field may appear, no field changes\n * meaning or goes away, and readers ignore fields they do not know. Anything else is version 2.\n *\n * @packageDocumentation\n */\n\nimport { createRequire } from \"node:module\";\n\nimport type { CalibrationBody, ComparisonBody } from \"./compare.js\";\nimport { BENCH_CONTRACT, type BenchContractShape } from \"./contract.js\";\nimport type { Environment } from \"./environment.js\";\nimport { WARMUP } from \"./measure.js\";\nimport type { ReadingBody } from \"./reading.js\";\n\n/** The version this package writes and reads. */\nexport const SCHEMA_VERSION = 1;\n\n/** Which build a document describes. */\nexport interface BuildRef {\n /** The entry measured, relative to the working directory. */\n readonly target: string;\n /** The commit it was built from, when known. */\n readonly commit: string | null;\n}\n\ninterface DocumentBase {\n readonly schemaVersion: 1;\n readonly tool: { readonly name: \"@cosyte/bench\"; readonly version: string };\n /** When the document was written, ISO 8601 UTC. */\n readonly createdAt: string;\n readonly suite: { readonly name: string; readonly file: string };\n readonly environment: Environment;\n /** The constants in force, so a document can be judged against the method that made it. */\n readonly contract: { readonly bench: BenchContractShape; readonly warmup: typeof WARMUP };\n}\n\n/** A results document. */\nexport type ResultsDocument = DocumentBase &\n (\n | { readonly kind: \"reading\"; readonly subject: BuildRef; readonly reading: ReadingBody }\n | {\n readonly kind: \"comparison\";\n readonly base: BuildRef;\n readonly head: BuildRef;\n readonly comparison: ComparisonBody;\n }\n | {\n readonly kind: \"calibration\";\n readonly base: BuildRef;\n readonly head: BuildRef;\n readonly calibration: CalibrationBody;\n }\n );\n\n/**\n * This package's version, read from its own manifest.\n *\n * @internal\n */\nexport function toolVersion(): string {\n const require = createRequire(import.meta.url);\n return (require(\"../package.json\") as { version: string }).version;\n}\n\n/**\n * The parts every document shares.\n *\n * @internal\n */\nexport function documentBase(\n suite: { name: string; file: string },\n environment: Environment,\n now: Date = new Date(),\n): DocumentBase {\n return {\n schemaVersion: SCHEMA_VERSION,\n tool: { name: \"@cosyte/bench\", version: toolVersion() },\n createdAt: now.toISOString(),\n suite,\n environment,\n contract: { bench: BENCH_CONTRACT, warmup: WARMUP },\n };\n}\n\n/** The JSON Schema keywords the results schema uses. */\ninterface Schema {\n readonly $ref?: string;\n readonly $defs?: Readonly<Record<string, Schema>>;\n readonly const?: unknown;\n readonly enum?: readonly unknown[];\n readonly type?: string | readonly string[];\n readonly minimum?: number;\n readonly required?: readonly string[];\n readonly properties?: Readonly<Record<string, Schema>>;\n readonly items?: Schema;\n readonly oneOf?: readonly Schema[];\n}\n\nconst num = { type: \"number\" } as const;\nconst int = { type: \"integer\", minimum: 0 } as const;\nconst str = { type: \"string\" } as const;\nconst strOrNull = { type: [\"string\", \"null\"] } as const;\nconst numOrNull = { type: [\"number\", \"null\"] } as const;\nconst nums = { type: \"array\", items: num } as const;\nconst skipped = {\n type: \"object\",\n required: [\"status\", \"reason\"],\n properties: { status: { const: \"skipped\" }, reason: str },\n} as const;\nconst measuredOrSkipped = (measured: Schema): Schema => ({ oneOf: [measured, skipped] });\nconst orNull = (s: Schema): Schema => ({ oneOf: [{ type: \"null\" }, s] });\n\n/**\n * The results schema, version 1, as JSON Schema (draft 2020-12). It holds what every reader relies\n * on; a document may carry more.\n *\n * @example\n * ```ts\n * import { RESULTS_SCHEMA } from \"@cosyte/bench\";\n *\n * RESULTS_SCHEMA.$id; // => \"https://github.com/cosyte/config/blob/main/packages/bench/schema/results-v1.schema.json\"\n * ```\n */\nexport const RESULTS_SCHEMA = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n $id: \"https://github.com/cosyte/config/blob/main/packages/bench/schema/results-v1.schema.json\",\n title: \"@cosyte/bench results, version 1\",\n type: \"object\",\n required: [\"schemaVersion\", \"kind\", \"tool\", \"createdAt\", \"suite\", \"environment\", \"contract\"],\n properties: {\n schemaVersion: { const: 1 },\n kind: { enum: [\"reading\", \"comparison\", \"calibration\"] },\n tool: {\n type: \"object\",\n required: [\"name\", \"version\"],\n properties: { name: { const: \"@cosyte/bench\" }, version: str },\n },\n createdAt: str,\n suite: { type: \"object\", required: [\"name\", \"file\"], properties: { name: str, file: str } },\n environment: { $ref: \"#/$defs/environment\" },\n contract: {\n type: \"object\",\n required: [\"bench\", \"warmup\"],\n properties: { bench: { type: \"object\" }, warmup: { type: \"object\" } },\n },\n },\n oneOf: [\n {\n required: [\"subject\", \"reading\"],\n properties: {\n kind: { const: \"reading\" },\n subject: { $ref: \"#/$defs/build\" },\n reading: { $ref: \"#/$defs/reading\" },\n },\n },\n {\n required: [\"base\", \"head\", \"comparison\"],\n properties: {\n kind: { const: \"comparison\" },\n base: { $ref: \"#/$defs/build\" },\n head: { $ref: \"#/$defs/build\" },\n comparison: { $ref: \"#/$defs/comparison\" },\n },\n },\n {\n required: [\"base\", \"head\", \"calibration\"],\n properties: {\n kind: { const: \"calibration\" },\n base: { $ref: \"#/$defs/build\" },\n head: { $ref: \"#/$defs/build\" },\n calibration: { $ref: \"#/$defs/calibration\" },\n },\n },\n ],\n $defs: {\n build: {\n type: \"object\",\n required: [\"target\", \"commit\"],\n properties: { target: str, commit: strOrNull },\n },\n environment: {\n type: \"object\",\n required: [\n \"node\",\n \"v8\",\n \"platform\",\n \"arch\",\n \"osRelease\",\n \"cpuModel\",\n \"logicalCpus\",\n \"totalMemoryBytes\",\n \"cgroupCpuMax\",\n \"runner\",\n ],\n properties: {\n node: str,\n v8: str,\n platform: str,\n arch: str,\n osRelease: str,\n cpuModel: strOrNull,\n logicalCpus: int,\n totalMemoryBytes: int,\n cgroupCpuMax: strOrNull,\n // Added within version 1, so not required: a document written before it is still valid.\n loadAverage: nums,\n runner: {\n type: \"object\",\n required: [\"ci\", \"provider\", \"class\"],\n properties: { ci: { type: \"boolean\" }, provider: strOrNull, class: str },\n },\n },\n },\n interval: orNull({\n type: \"object\",\n required: [\"low\", \"high\", \"rank\", \"tail\"],\n properties: { low: num, high: num, rank: int, tail: num },\n }),\n caseComparison: {\n type: \"object\",\n required: [\n \"benchmark\",\n \"size\",\n \"baseMsPerOp\",\n \"headMsPerOp\",\n \"ratios\",\n \"medianRatio\",\n \"interval\",\n \"verdict\",\n \"skipReason\",\n ],\n properties: {\n benchmark: str,\n size: str,\n baseMsPerOp: nums,\n headMsPerOp: nums,\n ratios: nums,\n medianRatio: numOrNull,\n interval: { $ref: \"#/$defs/interval\" },\n verdict: {\n enum: [\"regression\", \"improvement\", \"no-regression\", \"inconclusive\", \"skipped\"],\n },\n skipReason: strOrNull,\n },\n },\n comparison: {\n type: \"object\",\n required: [\"rounds\", \"threshold\", \"alpha\", \"inject\", \"cases\"],\n properties: {\n rounds: int,\n threshold: num,\n alpha: num,\n inject: num,\n cases: { type: \"array\", items: { $ref: \"#/$defs/caseComparison\" } },\n },\n },\n rate: {\n type: \"object\",\n required: [\"events\", \"trials\", \"rate\", \"upperBound\"],\n properties: { events: int, trials: int, rate: num, upperBound: num },\n },\n calibration: {\n type: \"object\",\n required: [\n \"inject\",\n \"comparisons\",\n \"runs\",\n \"perCase\",\n \"perComparison\",\n \"verdicts\",\n \"requiredRule\",\n ],\n properties: {\n inject: num,\n comparisons: int,\n runs: {\n type: \"array\",\n items: { type: \"array\", items: { $ref: \"#/$defs/caseComparison\" } },\n },\n perCase: { $ref: \"#/$defs/rate\" },\n perComparison: { $ref: \"#/$defs/rate\" },\n // Added within version 1, so optional: documents written before it validate unchanged.\n skippedComparisons: { $ref: \"#/$defs/rate\" },\n verdicts: { type: \"object\" },\n observed: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"benchmark\", \"size\", \"rounds\", \"medianRatio\"],\n properties: { benchmark: str, size: str, rounds: int, medianRatio: numOrNull },\n },\n },\n requiredRule: {\n type: \"object\",\n required: [\"applies\", \"met\", \"reason\"],\n properties: { applies: { type: \"boolean\" }, met: { type: \"boolean\" }, reason: str },\n },\n },\n },\n reading: {\n type: \"object\",\n required: [\"processes\", \"cases\", \"importCost\"],\n properties: {\n processes: int,\n cases: { type: \"array\", items: { $ref: \"#/$defs/caseReading\" } },\n importCost: orNull({\n type: \"object\",\n required: [\n \"runs\",\n \"coldImportMs\",\n \"medianMs\",\n \"p95Ms\",\n \"emptyImportMs\",\n \"emptyMedianMs\",\n \"files\",\n \"totalBytes\",\n \"totalGzipBytes\",\n ],\n properties: {\n runs: int,\n coldImportMs: nums,\n medianMs: num,\n p95Ms: num,\n emptyImportMs: nums,\n emptyMedianMs: num,\n files: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"path\", \"bytes\", \"gzipBytes\"],\n properties: { path: str, bytes: int, gzipBytes: int },\n },\n },\n totalBytes: int,\n totalGzipBytes: int,\n },\n }),\n },\n },\n caseReading: {\n type: \"object\",\n required: [\n \"benchmark\",\n \"size\",\n \"inputsPerPass\",\n \"bytesPerPass\",\n \"throughput\",\n \"latency\",\n \"allocations\",\n \"peak\",\n \"longRun\",\n ],\n properties: {\n benchmark: str,\n size: str,\n inputsPerPass: int,\n bytesPerPass: numOrNull,\n throughput: measuredOrSkipped({\n type: \"object\",\n required: [\"status\", \"processes\", \"medianMsPerOp\", \"opsPerSecond\", \"bytesPerSecond\"],\n properties: {\n status: { const: \"measured\" },\n processes: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"samplesMsPerOp\", \"medianMsPerOp\"],\n properties: { samplesMsPerOp: nums, medianMsPerOp: num },\n },\n },\n medianMsPerOp: num,\n opsPerSecond: num,\n bytesPerSecond: numOrNull,\n },\n }),\n latency: orNull({\n type: \"object\",\n required: [\"status\", \"calls\", \"timerOverheadNs\", \"p50Ns\"],\n properties: {\n status: { enum: [\"measured\", \"skipped\"] },\n calls: int,\n timerOverheadNs: num,\n p50Ns: numOrNull,\n p95Ns: numOrNull,\n p99Ns: numOrNull,\n maxNs: num,\n },\n }),\n allocations: orNull(\n measuredOrSkipped({\n type: \"object\",\n required: [\"status\", \"windowOps\", \"heapBytesPerOp\", \"externalBytesPerOp\"],\n properties: {\n status: { const: \"measured\" },\n windowOps: int,\n heapBytesPerOp: num,\n externalBytesPerOp: num,\n },\n }),\n ),\n peak: orNull(\n measuredOrSkipped({\n type: \"object\",\n required: [\"status\", \"calls\", \"peakHeapBytes\", \"medianPeakHeapBytes\"],\n properties: {\n status: { const: \"measured\" },\n calls: int,\n peakHeapBytes: num,\n medianPeakHeapBytes: num,\n },\n }),\n ),\n longRun: orNull(\n measuredOrSkipped({\n type: \"object\",\n required: [\"status\", \"verdict\", \"ops\", \"opsPerRound\", \"settledHeap\", \"slopeBytesPerOp\"],\n properties: {\n status: { const: \"measured\" },\n verdict: { enum: [\"flat\", \"growing\"] },\n ops: int,\n opsPerRound: int,\n settledHeap: nums,\n slopeBytesPerOp: num,\n },\n }),\n ),\n },\n },\n },\n} as const;\n\nfunction typeOf(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n if (Number.isInteger(value)) return \"integer\";\n return typeof value;\n}\n\nfunction typeMatches(value: unknown, type: string): boolean {\n const actual = typeOf(value);\n return actual === type || (type === \"number\" && actual === \"integer\");\n}\n\nfunction resolveRef(ref: string, root: Schema): Schema {\n const target = root.$defs?.[ref.replace(\"#/$defs/\", \"\")];\n if (target === undefined) throw new Error(`schema has no definition ${ref}`);\n return target;\n}\n\n/**\n * Check a value against the subset of JSON Schema the results schema uses (`type`, `const`, `enum`,\n * `required`, `properties`, `items`, `minimum`, `oneOf`, `$ref` into `$defs`) and return every\n * problem, each with its JSON pointer. An empty list means the value conforms.\n *\n * @internal\n */\nexport function validate(value: unknown, schema: Schema, root: Schema = schema, at = \"\"): string[] {\n const problems: string[] = [];\n const here = at === \"\" ? \"/\" : at;\n if (typeof schema.$ref === \"string\")\n return validate(value, resolveRef(schema.$ref, root), root, at);\n if (\"const\" in schema && value !== schema.const)\n problems.push(`${here}: must be ${JSON.stringify(schema.const)}`);\n if (schema.enum !== undefined && !schema.enum.includes(value)) {\n problems.push(\n `${here}: must be one of ${schema.enum.map((e) => JSON.stringify(e)).join(\", \")}`,\n );\n }\n if (schema.type !== undefined) {\n const types: readonly string[] = typeof schema.type === \"string\" ? [schema.type] : schema.type;\n if (!types.some((t) => typeMatches(value, t))) {\n problems.push(`${here}: must be ${types.join(\" or \")}, is ${typeOf(value)}`);\n return problems;\n }\n }\n if (typeof value === \"number\" && value < (schema.minimum ?? -Infinity)) {\n problems.push(`${here}: must be at least ${String(schema.minimum)}`);\n }\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n const record = value as Record<string, unknown>;\n for (const key of schema.required ?? []) {\n if (!(key in record)) problems.push(`${here}: is missing \"${key}\"`);\n }\n for (const [key, sub] of Object.entries(schema.properties ?? {})) {\n if (key in record) problems.push(...validate(record[key], sub, root, `${at}/${key}`));\n }\n }\n if (Array.isArray(value) && schema.items !== undefined) {\n const items = schema.items;\n value.forEach((item, i) => problems.push(...validate(item, items, root, `${at}/${String(i)}`)));\n }\n if (schema.oneOf !== undefined) {\n const results = schema.oneOf.map((s) => validate(value, s, root, at));\n const passing = results.filter((r) => r.length === 0).length;\n if (passing !== 1) {\n problems.push(\n `${here}: must match exactly one of ${String(results.length)} shapes, matches ${String(passing)}`,\n );\n // The nearest shape's problems say what to fix. With two or more matching, the nearest has\n // none, so this adds nothing.\n problems.push(...results.reduce((a, b) => (b.length < a.length ? b : a)));\n }\n }\n return problems;\n}\n\n/**\n * Parse and check a results document. Throws a `TypeError` listing every problem when the text is\n * not JSON, is a version this package does not read, or does not match the schema.\n *\n * @example\n * ```ts\n * import { readResults } from \"@cosyte/bench\";\n *\n * try {\n * readResults('{\"schemaVersion\": 2}');\n * } catch (error) {\n * String(error).includes(\"version 2\"); // => true\n * }\n * ```\n */\nexport function readResults(text: string): ResultsDocument {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n throw new TypeError(\"@cosyte/bench: the results are not JSON\");\n }\n const version = (value as { schemaVersion?: unknown } | null)?.schemaVersion;\n if (version !== SCHEMA_VERSION) {\n throw new TypeError(\n `@cosyte/bench: results version ${String(version)} is not one this package reads (${String(SCHEMA_VERSION)})`,\n );\n }\n const problems = validate(value, RESULTS_SCHEMA);\n if (problems.length > 0)\n throw new TypeError(\n `@cosyte/bench: the results do not match the schema:\\n${problems.join(\"\\n\")}`,\n );\n return value as ResultsDocument;\n}\n","/**\n * The `cosyte-bench` command line. Exit codes follow the repository's gate rule: 0 clean, 1 a\n * finding (a regression, or a results file that does not match the schema), 2 could not measure or\n * could not read its input.\n *\n * @packageDocumentation\n */\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { relative, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport {\n calibrateComparison,\n compareBuilds,\n comparisonExitCode,\n type JobRunner,\n} from \"./compare.js\";\nimport type { Environment } from \"./environment.js\";\nimport type { ImportCostReport } from \"./import-cost.js\";\nimport { readBuild } from \"./reading.js\";\nimport { renderMarkdown } from \"./report.js\";\nimport { documentBase, readResults, type ResultsDocument } from \"./results.js\";\nimport { checkSuite, type BenchSuite } from \"./suite.js\";\n\n/** What `main` writes to and reads from. Real streams in the bin; buffers in tests. */\nexport interface MainIo {\n readonly stdout: (text: string) => void;\n readonly stderr: (text: string) => void;\n readonly cwd: string;\n readonly env: NodeJS.ProcessEnv;\n /** Runs one measuring job: `runInChild` in the bin. */\n readonly runJob: JobRunner;\n /** Measures cold import cost: `measureImportCost` in the bin. */\n readonly measureImport: (target: string) => Promise<ImportCostReport>;\n /** Describes the machine: `environment` in the bin. */\n readonly environment: () => Environment;\n readonly now: () => Date;\n}\n\n/**\n * The usage text.\n *\n * @internal\n */\nexport const USAGE = `Usage:\n cosyte-bench run --suite <file> --target <file> [--processes <n>] [--no-memory] [--no-import]\n [--commit <sha>] [--only <name>]... [--out <file.json>] [--summary <file.md>]\n cosyte-bench compare --suite <file> --base <file> --head <file> [--base-commit <sha>]\n [--head-commit <sha>] [--only <name>]... [--out <file.json>] [--summary <file.md>]\n cosyte-bench calibrate --suite <file> --base <file> --head <file> --comparisons <n>\n [--inject <fraction>] [--only <name>]... [--out <file.json>] [--summary <file.md>]\n cosyte-bench check <results.json>\n\nExit codes: 0 clean, 1 a finding (a regression, or results that do not match the schema),\n2 could not measure or could not read its input.\n`;\n\n/** A bad command line. */\nclass UsageError extends Error {}\n\nconst VALUE_FLAGS = new Set([\n \"--suite\",\n \"--target\",\n \"--base\",\n \"--head\",\n \"--out\",\n \"--summary\",\n \"--commit\",\n \"--base-commit\",\n \"--head-commit\",\n \"--processes\",\n \"--comparisons\",\n \"--inject\",\n \"--only\",\n]);\nconst BOOLEAN_FLAGS = new Set([\"--no-memory\", \"--no-import\"]);\n\n/** The flags each command takes. Any other is refused rather than quietly ignored. */\nconst FLAGS_FOR: Readonly<Record<\"run\" | \"compare\" | \"calibrate\", readonly string[]>> = {\n run: [\n \"--suite\",\n \"--target\",\n \"--processes\",\n \"--no-memory\",\n \"--no-import\",\n \"--commit\",\n \"--only\",\n \"--out\",\n \"--summary\",\n ],\n compare: [\n \"--suite\",\n \"--base\",\n \"--head\",\n \"--base-commit\",\n \"--head-commit\",\n \"--only\",\n \"--out\",\n \"--summary\",\n ],\n calibrate: [\n \"--suite\",\n \"--base\",\n \"--head\",\n \"--comparisons\",\n \"--inject\",\n \"--only\",\n \"--out\",\n \"--summary\",\n ],\n};\n\n/**\n * Parsed flags: each value flag's values in order, each boolean flag present or not, and the\n * positional arguments.\n *\n * @internal\n */\nexport interface ParsedArgs {\n readonly values: ReadonlyMap<string, readonly string[]>;\n readonly flags: ReadonlySet<string>;\n readonly positional: readonly string[];\n}\n\n/**\n * Parse flags. Unknown flags and a value flag with no value are refused.\n *\n * @internal\n */\nexport function parseArgs(argv: readonly string[]): ParsedArgs {\n const values = new Map<string, string[]>();\n const flags = new Set<string>();\n const positional: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i] as string;\n if (VALUE_FLAGS.has(arg)) {\n const value = argv[i + 1];\n if (value === undefined || value.startsWith(\"--\"))\n throw new UsageError(`${arg} needs a value`);\n values.set(arg, [...(values.get(arg) ?? []), value]);\n i++;\n } else if (BOOLEAN_FLAGS.has(arg)) {\n flags.add(arg);\n } else if (arg.startsWith(\"--\")) {\n throw new UsageError(`unknown flag ${arg}`);\n } else {\n positional.push(arg);\n }\n }\n return { values, flags, positional };\n}\n\nfunction one(args: ParsedArgs, flag: string): string | undefined {\n const all = args.values.get(flag);\n if (all !== undefined && all.length > 1) throw new UsageError(`${flag} given more than once`);\n return all?.[0];\n}\n\nfunction required(args: ParsedArgs, flag: string): string {\n const value = one(args, flag);\n if (value === undefined) throw new UsageError(`${flag} is required`);\n return value;\n}\n\nfunction count(args: ParsedArgs, flag: string, fallback: number): number {\n const raw = one(args, flag);\n if (raw === undefined) return fallback;\n const n = Number(raw);\n if (!Number.isInteger(n) || n < 1) throw new UsageError(`${flag} must be a positive integer`);\n return n;\n}\n\nfunction fraction(args: ParsedArgs, flag: string): number {\n const raw = one(args, flag);\n if (raw === undefined) return 0;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < 0 || n > 1)\n throw new UsageError(`${flag} must be a fraction from 0 to 1`);\n return n;\n}\n\nasync function loadSuite(file: string): Promise<BenchSuite<unknown>> {\n const module = (await import(pathToFileURL(file).href)) as { default?: unknown };\n return checkSuite(module.default);\n}\n\n/**\n * Run the command line. Returns the exit code.\n *\n * @internal\n */\nexport async function main(argv: readonly string[], io: MainIo): Promise<number> {\n const [command, ...rest] = argv;\n try {\n if (command === undefined || command === \"--help\" || command === \"help\") {\n io.stdout(USAGE);\n return command === undefined ? 2 : 0;\n }\n const args = parseArgs(rest);\n const abs = (p: string) => resolve(io.cwd, p);\n const rel = (p: string) => relative(io.cwd, abs(p));\n const progress = (line: string) => {\n io.stderr(`[cosyte-bench] ${line}\\n`);\n };\n const finish = (doc: ResultsDocument, code: number): number => {\n const out = one(args, \"--out\");\n const summary = one(args, \"--summary\");\n const markdown = renderMarkdown(doc);\n if (out !== undefined) writeFileSync(abs(out), `${JSON.stringify(doc, null, 2)}\\n`);\n if (summary !== undefined) writeFileSync(abs(summary), markdown);\n io.stdout(markdown);\n return code;\n };\n const overrides = { runJob: io.runJob, onProgress: progress };\n\n if (command === \"check\") {\n if (args.values.size > 0 || args.flags.size > 0) throw new UsageError(\"check takes no flags\");\n const file = args.positional[0];\n if (file === undefined) throw new UsageError(\"check needs a results file\");\n let text: string;\n try {\n text = String(readFileSync(abs(file)));\n } catch {\n io.stderr(`[cosyte-bench] cannot read ${rel(file)}\\n`);\n return 2;\n }\n try {\n const doc = readResults(text);\n io.stdout(\n `${rel(file)}: a valid ${doc.kind} document, schema version ${String(doc.schemaVersion)}\\n`,\n );\n return 0;\n } catch (error) {\n io.stderr(`[cosyte-bench] ${rel(file)}: ${(error as Error).message}\\n`);\n return 1;\n }\n }\n\n if (command !== \"run\" && command !== \"compare\" && command !== \"calibrate\") {\n throw new UsageError(`unknown command ${command}`);\n }\n for (const flag of [...args.values.keys(), ...args.flags]) {\n if (!FLAGS_FOR[command].includes(flag))\n throw new UsageError(`${flag} does not apply to ${command}`);\n }\n if (args.positional.length > 0)\n throw new UsageError(`unexpected argument ${String(args.positional[0])}`);\n const suiteFile = abs(required(args, \"--suite\"));\n const only = args.values.get(\"--only\") ?? [];\n\n if (command === \"run\") {\n const target = required(args, \"--target\");\n const processes = count(args, \"--processes\", 3);\n const suite = await loadSuite(suiteFile);\n const reading = await readBuild({\n suiteFile,\n suite,\n target: abs(target),\n only,\n processes,\n memory: !args.flags.has(\"--no-memory\"),\n importCost: !args.flags.has(\"--no-import\"),\n ...overrides,\n measureImport: io.measureImport,\n });\n const commit = one(args, \"--commit\") ?? io.env[\"GITHUB_SHA\"] ?? null;\n return finish(\n {\n ...documentBase({ name: suite.name, file: rel(suiteFile) }, io.environment(), io.now()),\n kind: \"reading\",\n subject: { target: rel(target), commit },\n reading,\n },\n 0,\n );\n }\n\n {\n const base = required(args, \"--base\");\n const head = required(args, \"--head\");\n // `--comparisons` and `--inject` belong to `calibrate` only (see FLAGS_FOR), so on `compare`\n // they read as absent: no comparisons and no slowdown.\n const comparisons = count(args, \"--comparisons\", 0);\n if (command === \"calibrate\" && comparisons === 0)\n throw new UsageError(\"--comparisons is required\");\n const inject = fraction(args, \"--inject\");\n const suite = await loadSuite(suiteFile);\n const common = {\n suiteFile,\n suite,\n base: abs(base),\n head: abs(head),\n only,\n inject,\n ...overrides,\n };\n const sides = {\n base: { target: rel(base), commit: one(args, \"--base-commit\") ?? null },\n head: { target: rel(head), commit: one(args, \"--head-commit\") ?? null },\n };\n const docBase = documentBase(\n { name: suite.name, file: rel(suiteFile) },\n io.environment(),\n io.now(),\n );\n if (command === \"compare\") {\n const comparison = await compareBuilds(common);\n return finish(\n { ...docBase, kind: \"comparison\", ...sides, comparison },\n comparisonExitCode(comparison),\n );\n }\n const calibration = await calibrateComparison({ ...common, comparisons });\n return finish({ ...docBase, kind: \"calibration\", ...sides, calibration }, 0);\n }\n } catch (error) {\n if (error instanceof UsageError) {\n io.stderr(`[cosyte-bench] ${error.message}\\n\\n${USAGE}`);\n return 2;\n }\n io.stderr(`[cosyte-bench] ${error instanceof Error ? error.message : String(error)}\\n`);\n return 2;\n }\n}\n","#!/usr/bin/env node\n/**\n * The `cosyte-bench` bin. Its logic is `main`, which the tests run in-process; this file is the\n * lines around it.\n *\n * @packageDocumentation\n */\n\nimport { environment } from \"./environment.js\";\nimport { measureImportCost } from \"./import-cost.js\";\nimport { main } from \"./main.js\";\nimport { runInChild } from \"./spawn.js\";\n\nprocess.exitCode = await main(process.argv.slice(2), {\n stdout: (text) => process.stdout.write(text),\n stderr: (text) => process.stderr.write(text),\n cwd: process.cwd(),\n env: process.env,\n runJob: (job) => runInChild(job),\n measureImport: (target) => measureImportCost(target),\n environment: () => environment(process.env),\n now: () => new Date(),\n});\n"]}
@@ -0,0 +1,2 @@
1
+
2
+ export { };
@@ -0,0 +1,42 @@
1
+ import { writeFileSync } from 'fs';
2
+ import { registerHooks } from 'module';
3
+ import 'os';
4
+ import 'path';
5
+ import { performance } from 'perf_hooks';
6
+ import { pathToFileURL, fileURLToPath } from 'url';
7
+ import 'zlib';
8
+
9
+ // src/import-cost.ts
10
+ function loadRecorder(files) {
11
+ return (url, context, nextLoad) => {
12
+ if (url.startsWith("file:")) files.add(fileURLToPath(url));
13
+ return nextLoad(url, context);
14
+ };
15
+ }
16
+ async function importMain(argv) {
17
+ if (argv.length !== 3) return 2;
18
+ const [mode, target, outFile] = argv;
19
+ if (mode !== "time" && mode !== "files") return 2;
20
+ const url = pathToFileURL(target).href;
21
+ if (mode === "time") {
22
+ const t0 = performance.now();
23
+ await import(url);
24
+ const ms = performance.now() - t0;
25
+ writeFileSync(outFile, JSON.stringify({ ms }));
26
+ return 0;
27
+ }
28
+ const files = /* @__PURE__ */ new Set();
29
+ const hooks = registerHooks({ load: loadRecorder(files) });
30
+ try {
31
+ await import(url);
32
+ } finally {
33
+ hooks.deregister();
34
+ }
35
+ writeFileSync(outFile, JSON.stringify({ files: [...files] }));
36
+ return 0;
37
+ }
38
+
39
+ // src/import-entry.ts
40
+ process.exitCode = await importMain(process.argv.slice(2));
41
+ //# sourceMappingURL=import-entry.mjs.map
42
+ //# sourceMappingURL=import-entry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/import-cost.ts","../src/import-entry.ts"],"names":[],"mappings":";;;;;;;;;AA+BO,SAAS,aAAa,KAAA,EAA8B;AACzD,EAAA,OAAO,CAAC,GAAA,EAAK,OAAA,EAAS,QAAA,KAAa;AACjC,IAAA,IAAI,GAAA,CAAI,WAAW,OAAO,CAAA,QAAS,GAAA,CAAI,aAAA,CAAc,GAAG,CAAC,CAAA;AACzD,IAAA,OAAO,QAAA,CAAS,KAAK,OAAO,CAAA;AAAA,EAC9B,CAAA;AACF;AASA,eAAsB,WAAW,IAAA,EAA0C;AACzE,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,CAAA;AAC9B,EAAA,MAAM,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,CAAA,GAAI,IAAA;AAChC,EAAA,IAAI,IAAA,KAAS,MAAA,IAAU,IAAA,KAAS,OAAA,EAAS,OAAO,CAAA;AAChD,EAAA,MAAM,GAAA,GAAM,aAAA,CAAc,MAAM,CAAA,CAAE,IAAA;AAClC,EAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,IAAA,MAAM,EAAA,GAAK,YAAY,GAAA,EAAI;AAC3B,IAAA,MAAM,OAAO,GAAA,CAAA;AACb,IAAA,MAAM,EAAA,GAAK,WAAA,CAAY,GAAA,EAAI,GAAI,EAAA;AAC/B,IAAA,aAAA,CAAc,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,EAAA,EAAI,CAAC,CAAA;AAC7C,IAAA,OAAO,CAAA;AAAA,EACT;AAIA,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,MAAM,QAAQ,aAAA,CAAc,EAAE,MAAM,YAAA,CAAa,KAAK,GAAG,CAAA;AACzD,EAAA,IAAI;AACF,IAAA,MAAM,OAAO,GAAA,CAAA;AAAA,EACf,CAAA,SAAE;AACA,IAAA,KAAA,CAAM,UAAA,EAAW;AAAA,EACnB;AACA,EAAA,aAAA,CAAc,OAAA,EAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,CAAC,GAAG,KAAK,CAAA,EAAG,CAAC,CAAA;AAE5D,EAAA,OAAO,CAAA;AACT;;;AC7DA,OAAA,CAAQ,WAAW,MAAM,UAAA,CAAW,QAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA","file":"import-entry.mjs","sourcesContent":["/**\n * Cold import time and the bytes an import loads.\n *\n * Each timed import runs in a fresh process with no compile cache, so nothing is compiled before it\n * starts. The same number of fresh processes import an empty module, interleaved with the target's,\n * so a reader can see how much of the time is the import machinery rather than the package.\n *\n * The bytes are the files Node actually loaded for the import, found by a module hook in one further\n * process that is not timed (the hook itself costs time). This is what a Node consumer loads; it is\n * not what a bundler would keep after tree shaking, which depends on what the consumer imports.\n *\n * @packageDocumentation\n */\n\nimport { readFileSync, rmSync, mkdtempSync, writeFileSync } from \"node:fs\";\nimport { registerHooks, type LoadHookSync as LoadHook } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { join, relative } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { gzipSync } from \"node:zlib\";\n\nimport { BENCH_CONTRACT } from \"./contract.js\";\nimport { BenchError, ENTRIES, runNode } from \"./spawn.js\";\nimport { median, nearestRank, round } from \"./stats.js\";\n\n/**\n * A module `load` hook that adds each `file:` module it sees to `files`, then loads it as usual.\n *\n * @internal\n */\nexport function loadRecorder(files: Set<string>): LoadHook {\n return (url, context, nextLoad) => {\n if (url.startsWith(\"file:\")) files.add(fileURLToPath(url));\n return nextLoad(url, context);\n };\n}\n\n/**\n * The cold import process's main. `argv` is `[mode, target, outFile]`: mode `time` imports the\n * target and writes `{ ms }`; mode `files` records every `file:` module loaded during the import and\n * writes `{ files }`. Returns the exit code.\n *\n * @internal\n */\nexport async function importMain(argv: readonly string[]): Promise<number> {\n if (argv.length !== 3) return 2;\n const [mode, target, outFile] = argv as [string, string, string];\n if (mode !== \"time\" && mode !== \"files\") return 2;\n const url = pathToFileURL(target).href;\n if (mode === \"time\") {\n const t0 = performance.now();\n await import(url);\n const ms = performance.now() - t0;\n writeFileSync(outFile, JSON.stringify({ ms }));\n return 0;\n }\n // Stryker disable all: this half runs only in a fresh Node process. Under the test runner an\n // import goes through Vite's loader, which Node's module hooks never see, and mutant switching\n // does not reach a child process; e2e.test.ts checks what it records in a real one.\n const files = new Set<string>();\n const hooks = registerHooks({ load: loadRecorder(files) });\n try {\n await import(url);\n } finally {\n hooks.deregister();\n }\n writeFileSync(outFile, JSON.stringify({ files: [...files] }));\n // Stryker restore all\n return 0;\n}\n\n/** One file an import loaded. */\nexport interface LoadedFile {\n /** Relative to the working directory, so no report carries a home directory. */\n readonly path: string;\n readonly bytes: number;\n /** Gzip at level 9: roughly what it costs to download. */\n readonly gzipBytes: number;\n}\n\n/** Cold import time and loaded bytes. */\nexport interface ImportCostReport {\n readonly runs: number;\n /** One per fresh process, milliseconds, in the order taken. */\n readonly coldImportMs: readonly number[];\n readonly medianMs: number;\n readonly p95Ms: number;\n /** The same for an empty module: the import machinery alone. */\n readonly emptyImportMs: readonly number[];\n readonly emptyMedianMs: number;\n readonly files: readonly LoadedFile[];\n readonly totalBytes: number;\n readonly totalGzipBytes: number;\n}\n\nasync function oneImport(\n entry: string,\n execArgv: readonly string[],\n mode: \"time\" | \"files\",\n target: string,\n dir: string,\n): Promise<unknown> {\n const out = join(dir, \"import.json\");\n rmSync(out, { force: true });\n const outcome = await runNode(entry, [mode, target, out], execArgv, 120_000);\n try {\n return JSON.parse(String(readFileSync(out)));\n } catch {\n throw new BenchError(\n `the cold import of ${relative(process.cwd(), target)} wrote no result. Its stderr ends:\\n${outcome.stderr}`,\n );\n }\n}\n\n/**\n * Measure a target's cold import time over `IMPORT_RUNS` fresh processes, an empty module's over as\n * many, interleaved, and the bytes one import loads.\n *\n * @internal\n */\nexport async function measureImportCost(\n target: string,\n entry: string = ENTRIES.importer,\n execArgv: readonly string[] = [],\n): Promise<ImportCostReport> {\n // Stryker disable next-line StringLiteral: the prefix only names the temporary directory.\n const dir = mkdtempSync(join(tmpdir(), \"cosyte-bench-import-\"));\n try {\n const empty = join(dir, \"empty.mjs\");\n // Stryker disable next-line StringLiteral: an empty file is an empty module too; the text only has to be one.\n writeFileSync(empty, \"export {};\\n\");\n const cold: number[] = [];\n const bare: number[] = [];\n for (let i = 0; i < BENCH_CONTRACT.IMPORT_RUNS; i++) {\n const order = i % 2 === 0 ? [target, empty] : [empty, target];\n for (const which of order) {\n const { ms } = (await oneImport(entry, execArgv, \"time\", which, dir)) as { ms: number };\n (which === target ? cold : bare).push(round(ms, 3));\n }\n }\n const { files } = (await oneImport(entry, execArgv, \"files\", target, dir)) as {\n files: string[];\n };\n const loaded = files\n .map((file) => {\n const bytes = readFileSync(file);\n return {\n path: relative(process.cwd(), file),\n bytes: bytes.length,\n gzipBytes: gzipSync(bytes, { level: 9 }).length,\n };\n })\n .sort((a, b) => a.path.localeCompare(b.path));\n return {\n runs: BENCH_CONTRACT.IMPORT_RUNS,\n coldImportMs: cold,\n medianMs: round(median(cold), 3),\n p95Ms: round(nearestRank(cold, 0.95), 3),\n emptyImportMs: bare,\n emptyMedianMs: round(median(bare), 3),\n files: loaded,\n totalBytes: loaded.reduce((n, f) => n + f.bytes, 0),\n totalGzipBytes: loaded.reduce((n, f) => n + f.gzipBytes, 0),\n };\n } finally {\n rmSync(dir, { recursive: true });\n }\n}\n","/**\n * The cold import process. `import-cost.ts` starts it with a target and an out file. Its logic is\n * `importMain`, which the tests run in-process; this file is the two lines around it.\n *\n * @packageDocumentation\n */\n\nimport { importMain } from \"./import-cost.js\";\n\nprocess.exitCode = await importMain(process.argv.slice(2));\n"]}