diff --git a/packages/tui/bench/_harness.ts b/packages/tui/bench/_harness.ts new file mode 100644 index 000000000..eab5833a7 --- /dev/null +++ b/packages/tui/bench/_harness.ts @@ -0,0 +1,19 @@ +/** + * Micro-benchmark harness shared by the tui bench scripts. + * + * `makeBench(iterations)` returns a `bench(name, fn)` that runs `fn` the given + * number of times, prints `: ms total (ms/op)`, and returns + * the total elapsed milliseconds. + */ +export function makeBench(iterations: number): (name: string, fn: () => void) => number { + return function bench(name: string, fn: () => void): number { + const start = Bun.nanoseconds(); + for (let i = 0; i < iterations; i++) { + fn(); + } + const elapsed = (Bun.nanoseconds() - start) / 1e6; + const perOp = (elapsed / iterations).toFixed(6); + console.log(`${name}: ${elapsed.toFixed(2)}ms total (${perOp}ms/op)`); + return elapsed; + }; +} diff --git a/packages/tui/bench/parse-key.ts b/packages/tui/bench/parse-key.ts index f8500b3f5..5e7659fe6 100644 --- a/packages/tui/bench/parse-key.ts +++ b/packages/tui/bench/parse-key.ts @@ -1,6 +1,7 @@ import { parseKey as nativeParseKey } from "@oh-my-pi/pi-natives"; import * as native from "../src/keys"; import * as js from "./_jskey"; +import { makeBench } from "./_harness"; const ITERATIONS = 2000; @@ -56,16 +57,7 @@ const samples = [ { name: "symbol /", data: "/", expected: "/" }, ]; -function bench(name: string, fn: () => void): number { - const start = Bun.nanoseconds(); - for (let i = 0; i < ITERATIONS; i++) { - fn(); - } - const elapsed = (Bun.nanoseconds() - start) / 1e6; - const perOp = (elapsed / ITERATIONS).toFixed(6); - console.log(`${name}: ${elapsed.toFixed(2)}ms total (${perOp}ms/op)`); - return elapsed; -} +const bench = makeBench(ITERATIONS); // Set to legacy mode for consistent comparison js.setKittyProtocolActive(true); diff --git a/packages/tui/bench/sanitize.ts b/packages/tui/bench/sanitize.ts index cad98a321..721d0b052 100644 --- a/packages/tui/bench/sanitize.ts +++ b/packages/tui/bench/sanitize.ts @@ -1,4 +1,5 @@ import { sanitizeText as currentSanitizeText } from "@oh-my-pi/pi-utils/sanitize-text"; +import { makeBench } from "./_harness"; const STRIP_RE = new RegExp( [ @@ -297,16 +298,7 @@ const samples = { const wrapWidth = 40; -function bench(name: string, fn: () => void): number { - const start = Bun.nanoseconds(); - for (let i = 0; i < ITERATIONS; i++) { - fn(); - } - const elapsed = (Bun.nanoseconds() - start) / 1e6; - const perOp = (elapsed / ITERATIONS).toFixed(6); - console.log(`${name}: ${elapsed.toFixed(2)}ms total (${perOp}ms/op)`); - return elapsed; -} +const bench = makeBench(ITERATIONS); console.log(`Text layout benchmark (${ITERATIONS} iterations)\n`); diff --git a/packages/tui/bench/text-layout.ts b/packages/tui/bench/text-layout.ts index da32f4ffe..650623ff2 100644 --- a/packages/tui/bench/text-layout.ts +++ b/packages/tui/bench/text-layout.ts @@ -1,5 +1,6 @@ import { visibleWidth, wrapTextWithAnsi, truncateToWidth, sliceWithWidth, extractSegments, Ellipsis } from "../src/utils"; import { matchesKey } from "../src/keys"; +import { makeBench } from "./_harness"; const ITERATIONS = 2000; @@ -13,16 +14,7 @@ const samples = { const wrapWidth = 40; -function bench(name: string, fn: () => void): number { - const start = Bun.nanoseconds(); - for (let i = 0; i < ITERATIONS; i++) { - fn(); - } - const elapsed = (Bun.nanoseconds() - start) / 1e6; - const perOp = (elapsed / ITERATIONS).toFixed(6); - console.log(`${name}: ${elapsed.toFixed(2)}ms total (${perOp}ms/op)`); - return elapsed; -} +const bench = makeBench(ITERATIONS); console.log(`Text layout benchmark (${ITERATIONS} iterations)\n`);