a73x

02224fad

Default bench + profile to ReleaseFast

a73x   2026-04-17 19:25

Commit message
Default bench + profile to ReleaseFast

Previously bench ran Debug and profile ran ReleaseSafe. Both left
ghostty-vt with slow_runtime_safety=true, so ~94% of profile samples
landed in Page.verifyIntegrity and baselines reflected
safety-check overhead rather than shipping perf.

- Propagate target + optimize to the ghostty lazyDependency so its
  terminalOptions() drops slow_runtime_safety for non-Debug modes.
- Add OPT ?= ReleaseFast to the Makefile; bench / profile /
  bench-baseline / bench-check all honor it.
- Profile now uses --call-graph dwarf,16384 for readable unwinds
  without frame pointers.

Baseline regenerated (row_rebuild p99: 2952us -> 169us; total p99:
3224us -> 289us).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Makefile
Old New
@@ -1,4 +1,5 @@
1 ZIG ?= zig 1 ZIG ?= zig
2 OPT ?= ReleaseFast
2 FLAMEGRAPH ?= inferno-flamegraph 3 FLAMEGRAPH ?= inferno-flamegraph
3 STACKCOLLAPSE ?= inferno-collapse-perf 4 STACKCOLLAPSE ?= inferno-collapse-perf
4 5
@@ -13,17 +14,15 @@ run: build
13 test: 14 test:
14 $(ZIG) build test 15 $(ZIG) build test
15 16
16 zig-out/bin/waystty: $(wildcard src/*.zig) $(wildcard src/tools/*.zig) $(wildcard shaders/*) 17 bench:
17 $(ZIG) build 18 $(ZIG) build -Doptimize=$(OPT)
18
19 bench: zig-out/bin/waystty
20 WAYSTTY_BENCH=1 ./zig-out/bin/waystty 2>bench.log || true 19 WAYSTTY_BENCH=1 ./zig-out/bin/waystty 2>bench.log || true
21 @echo "--- frame timing ---" 20 @echo "--- frame timing ---"
22 @grep -A 12 "waystty frame timing" bench.log || echo "(no timing data found)" 21 @grep -A 12 "waystty frame timing" bench.log || echo "(no timing data found)"
23 22
24 profile: 23 profile:
25 $(ZIG) build -Doptimize=ReleaseSafe 24 $(ZIG) build -Doptimize=$(OPT)
26 WAYSTTY_BENCH=1 perf record -g -F 999 --no-inherit -o perf.data -- \ 25 WAYSTTY_BENCH=1 perf record -g --call-graph dwarf,16384 -F 999 --no-inherit -o perf.data -- \
27 ./zig-out/bin/waystty 2>bench.log 26 ./zig-out/bin/waystty 2>bench.log
28 perf script -i perf.data \ 27 perf script -i perf.data \
29 | $(STACKCOLLAPSE) \ 28 | $(STACKCOLLAPSE) \
@@ -39,10 +38,10 @@ golden-update:
39 WAYSTTY_GOLDEN_UPDATE=1 $(ZIG) build test-render 38 WAYSTTY_GOLDEN_UPDATE=1 $(ZIG) build test-render
40 39
41 bench-baseline: 40 bench-baseline:
42 $(ZIG) build bench-baseline 41 $(ZIG) build bench-baseline -Doptimize=$(OPT)
43 42
44 bench-check: 43 bench-check:
45 $(ZIG) build bench-check 44 $(ZIG) build bench-check -Doptimize=$(OPT)
46 45
47 clean: 46 clean:
48 rm -rf zig-out .zig-cache perf.data bench.log flamegraph.svg tests/golden/output 47 rm -rf zig-out .zig-cache perf.data bench.log flamegraph.svg tests/golden/output
build.zig
Old New
@@ -23,7 +23,10 @@ pub fn build(b: *std.Build) void {
23 23
24 // Lazy-fetch the ghostty dependency. On the first invocation this 24 // Lazy-fetch the ghostty dependency. On the first invocation this
25 // materializes the package; subsequent builds use the local cache. 25 // materializes the package; subsequent builds use the local cache.
26 const ghostty_dep = b.lazyDependency("ghostty", .{}); 26 const ghostty_dep = b.lazyDependency("ghostty", .{
27 .target = target,
28 .optimize = optimize,
29 });
27 30
28 // zig-wayland scanner — generates protocol bindings at build time 31 // zig-wayland scanner — generates protocol bindings at build time
29 const wayland_dep = b.dependency("wayland", .{}); 32 const wayland_dep = b.dependency("wayland", .{});
tests/bench/baseline.json
Old New
@@ -1,38 +1,38 @@
1 { 1 {
2 "workload_sha": "a79a3b3449f44938e56bc64555a95cc5234c73a1dc4b05c4e8cc17aa0209d1df", 2 "workload_sha": "a79a3b3449f44938e56bc64555a95cc5234c73a1dc4b05c4e8cc17aa0209d1df",
3 "zig_version": "0.15.2", 3 "zig_version": "0.15.2",
4 "waystty_sha": "321b22803777191c86a97ad7ce7edba9b90b6c9e", 4 "waystty_sha": "b7e080ca7f2ef8d5cd9d32eac59c264ffbdae99a",
5 "frame_count": 65, 5 "frame_count": 202,
6 "sections": { 6 "sections": {
7 "snapshot": { 7 "snapshot": {
8 "min": 6, 8 "min": 0,
9 "avg": 42, 9 "avg": 1,
10 "p99": 216, 10 "p99": 3,
11 "max": 735 11 "max": 74
12 }, 12 },
13 "row_rebuild": { 13 "row_rebuild": {
14 "min": 121, 14 "min": 10,
15 "avg": 1450, 15 "avg": 81,
16 "p99": 3344, 16 "p99": 193,
17 "max": 3383 17 "max": 233
18 }, 18 },
19 "atlas_upload": { 19 "atlas_upload": {
20 "min": 0, 20 "min": 0,
21 "avg": 4, 21 "avg": 1,
22 "p99": 47, 22 "p99": 19,
23 "max": 57 23 "max": 24
24 }, 24 },
25 "instance_upload": { 25 "instance_upload": {
26 "min": 3, 26 "min": 0,
27 "avg": 17, 27 "avg": 1,
28 "p99": 75, 28 "p99": 18,
29 "max": 83 29 "max": 33
30 }, 30 },
31 "gpu_submit": { 31 "gpu_submit": {
32 "min": 22, 32 "min": 18,
33 "avg": 48, 33 "avg": 52,
34 "p99": 99, 34 "p99": 150,
35 "max": 106 35 "max": 294
36 } 36 }
37 } 37 }
38 } 38 }
38 \ No newline at end of file 38 \ No newline at end of file