From 4e224b7c7e67fafcbe7359fcf534048e254b701d Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 29 Sep 2026 13:19:08 -0300 Subject: The theme's chrome is worked out once, not per grapheme; still post passes let the GUI rest; a perf gate somtrmsz's contrast floors made ChromeTheme.fromTheme run its focus-tint and separator searches (pow calls each), and Output's RowDecoration.styleAt called it for every grapheme of every highlighted row: the 50k-line file's render went from 0.11 ms to 13 ms. Pardes.bodyChrome now keeps the theme's chrome, worked out again only when the theme differs; recolorSyntax asks for it once a decorated row, and a plain row (nearly every row of a file) never asks. ReleaseFast, medium fixture, median us, before -> after (main): render 13150 -> 76 (111), key-down 14658 -> 79 (110), wheel 13589 -> 76 (109), open 14891 -> 2095 (2055), edit-char 16703 -> 3006 (1251; the rest of that gap is editing and tree-sitter, not this). Post.animating asked for frames whenever the window had focus and any pass was ready, so a still pass kept the GUI drawing at the display's rate (Bloom: 49% of a core idle, in a hidden test window). A pass now says whether it moves on its own: the CRT (its hum and dither) and a Shadertoy file whose source reads iTime, iFrame or iDate (shader_build.readsTime; the flag rides the wire's post message); Bloom, Vignette and Grain are still. Bloom idle: 49% -> 1.2%, as with no pass. zig build perf-gate: the 50k-line file's gestures, each's fastest sample within 3x of the recorded baseline's (test/perf-baseline-- .json, recorded from this build), run with every unit-test. On the regressed code it fails at 180x for render. --- build.zig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'build.zig') diff --git a/build.zig b/build.zig index 48987edf..79de8a81 100644 --- a/build.zig +++ b/build.zig @@ -1282,6 +1282,18 @@ pub fn build(b: *std.Build) void { run_perf.setCwd(b.path(".")); const perf_step = b.step("perf", "gesture latency or bounded terminal stress (-- [--json] [--reps N] [--base old.json] [--terminal-mib N])"); perf_step.dependOn(&run_perf.step); + // The gate: the 50k-line file's gestures against the baseline this + // build shape recorded, each within 3x of its best. Record one with + // `zig build perf -Dplatform=P [-Doptimize=O] -- --only medium + // --reps 10 --json > test/perf-baseline-P-O.json` (a build that is + // known good). ponytail: the numbers are this machine's; another + // machine records its own. + const perf_gate = b.addRunArtifact(perf); + perf_gate.has_side_effects = true; + perf_gate.setCwd(b.path(".")); + perf_gate.addArgs(&.{ "--only", "medium", "--reps", "10", "--base", b.fmt("test/perf-baseline-{t}-{t}.json", .{ platform, optimize }), "--max-ratio", "3" }); + const perf_gate_step = b.step("perf-gate", "fail when a gesture on the 50k-line file takes over 3x its recorded baseline (test/perf-baseline--.json)"); + perf_gate_step.dependOn(&perf_gate.step); const perf_tests = b.addTest(.{ .root_module = b.createModule(.{ .target = target, @@ -1430,6 +1442,9 @@ pub fn build(b: *std.Build) void { b.step("history", "compare command output and test/build runtime across jj revisions").dependOn(&run_history.step); const unit_step = b.step("unit-test", "run native shell and module unit tests"); + // The perf gate runs with every unit-test (a regression like a + // contrast search per grapheme costs 100x, far past the gate). + unit_step.dependOn(perf_gate_step); const unit_match = testMatch(b, unit_profile, test_filters, unit_step); const lspbench_tests = b.addTest(.{ .root_module = lspbench.root_module, .filters = test_filters }); const run_lspbench_tests = b.addRunArtifact(lspbench_tests); -- cgit v1.3