import path from "node:path"; import { createTestSession } from "@marcfargas/pi-test-harness"; import { findNu } from "../runtime.ts"; const rounds = Number(process.env.NUSHELL_BENCH_ROUNDS ?? 25); const warmups = Number(process.env.NUSHELL_BENCH_WARMUPS ?? 3); if ( !Number.isSafeInteger(rounds) || rounds < 1 || !Number.isSafeInteger(warmups) || warmups < 0 ) throw new Error( "Benchmark rounds must be positive integers; warmups may be zero", ); if (!findNu()) throw new Error("nu executable missing on PATH"); const t = await createTestSession({ cwd: process.cwd(), extensions: [path.resolve(import.meta.dirname, "../index.ts")], }); try { const runner = t.session.extensionRunner; const ctx = runner.createCommandContext(); const fresh = runner.extensions[0]?.tools.get("nu")?.definition; const persistent = runner.extensions[0]?.tools.get("nu_session")?.definition; if (!fresh || !persistent) throw new Error("Nushell tools not registered"); const exec = async (tool: typeof fresh) => { const result = await tool.execute( "bench", { command: "1 + 2" }, undefined, undefined, ctx, ); if ( !result.content.some( (part) => part.type === "text" && part.text.includes("3"), ) ) throw new Error("Incorrect benchmark output"); }; const measure = async ( name: string, call: () => Promise, record: boolean, ) => { const start = process.hrtime.bigint(); await call(); if (record) console.log(`${name}\t1\t${process.hrtime.bigint() - start} ns/op`); }; console.log(`goos: ${process.platform}`); console.log(`goarch: ${process.arch}`); console.log("pkg: pi-ext/nushell"); console.log(`node: ${process.version}`); for (let index = -warmups; index < rounds; index++) { const record = index >= 0; await runner.getCommand("nushell")?.handler("reset", ctx); await measure("BenchmarkNuSessionCold", () => exec(persistent), record); if (index % 2 === 0) { await measure("BenchmarkNuFresh", () => exec(fresh), record); await measure("BenchmarkNuSessionWarm", () => exec(persistent), record); } else { await measure("BenchmarkNuSessionWarm", () => exec(persistent), record); await measure("BenchmarkNuFresh", () => exec(fresh), record); } } await runner.getCommand("nushell")?.handler("reset", ctx); } finally { t.dispose(); }