repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
scripts/codegen/pi-ext-debug.bench.mjs
Raw// Benchmark the generated debug writer the way Pi startup exercises it:
// one fresh module copy per extension, enabled through user settings, logging
// against already-existing private directories. Prints Go benchmark lines.
// Usage: node pi-ext-debug.bench.mjs [template.ts]
import { spawnSync } from "node:child_process";
import {
mkdirSync,
mkdtempSync,
readFileSync,
rmSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
const EXTENSIONS = 40;
const ROUNDS = Number(process.env.PI_EXT_DEBUG_BENCH_ROUNDS ?? 30);
const WARM_RECORDS = 2_000;
const here = dirname(fileURLToPath(import.meta.url));
if (process.argv[2] === "--child") {
const [, , , moduleDir] = process.argv;
const started = process.hrtime.bigint();
const loaded = [];
for (let index = 0; index < EXTENSIONS; index++) {
const module = await import(
pathToFileURL(join(moduleDir, `ext-${index}.ts`)).href
);
const debug = module.defineDebug({
events: ["session.start", "session.shutdown"],
spans: ["catalog.refresh"],
fields: { count: "number", network: "boolean", outcome: ["ok"] },
});
debug.dbg?.("session.start", { count: index });
for (let refresh = 0; refresh < 2; refresh++)
debug.span?.("catalog.refresh", { network: false })("finish", {
outcome: "ok",
});
loaded.push(debug);
}
const startup = process.hrtime.bigint() - started;
const [first] = loaded;
const warmStarted = process.hrtime.bigint();
for (let index = 0; index < WARM_RECORDS; index++)
first.dbg?.("session.start", { count: index });
const warm = (process.hrtime.bigint() - warmStarted) / BigInt(WARM_RECORDS);
for (const debug of loaded) debug.closeDebug();
console.log(`${startup} ${warm}`);
process.exit(0);
}
const template = resolve(
process.argv[2] ?? join(here, "templates", "pi-ext-debug.ts"),
);
const root = mkdtempSync(join(tmpdir(), "pi-ext-debug-bench-"));
try {
const moduleDir = join(root, "modules");
mkdirSync(moduleDir);
const source = readFileSync(template, "utf8");
for (let index = 0; index < EXTENSIONS; index++)
writeFileSync(
join(moduleDir, `ext-${index}.ts`),
source.replaceAll("{{extension-slug}}", `bench-${index}`),
);
const agentDir = join(root, "agent");
mkdirSync(agentDir);
// Realistic user settings size (~4.5 KB) with global debug selection.
writeFileSync(
join(agentDir, "settings.json"),
JSON.stringify({
"pi-ext": { debug: true },
padding: Array.from({ length: 60 }, (_, index) => ({
key: `setting-${index}`,
value: "x".repeat(48),
})),
}),
);
const env = {
...process.env,
HOME: join(root, "home"),
XDG_STATE_HOME: join(root, "state"),
PI_CODING_AGENT_DIR: agentDir,
};
const run = () => {
const result = spawnSync(
process.execPath,
[
"--no-warnings",
"--experimental-strip-types",
fileURLToPath(import.meta.url),
"--child",
moduleDir,
],
{ env, encoding: "utf8" },
);
if (result.status !== 0) throw new Error(result.stderr);
return result.stdout.trim().split(" ");
};
// First run creates the directories; later runs match normal startups.
for (let index = 0; index < 3; index++) run();
console.log(`goos: ${process.platform}`);
console.log(`goarch: ${process.arch}`);
console.log("pkg: pi-ext/debug");
for (let round = 0; round < ROUNDS; round++) {
const [startup, warm] = run();
console.log(`BenchmarkDebugStartup${EXTENSIONS}\t1\t${startup} ns/op`);
console.log(`BenchmarkDebugRecordWarm\t${WARM_RECORDS}\t${warm} ns/op`);
}
} finally {
rmSync(root, { recursive: true, force: true });
}