bench: measure ghostty's release and tip together, and harden wl-latency #379

Merged
natsukium merged 3 commits from bench/wl-latency-wouldblock into main 2026-09-24 18:37:13 +09:00
Owner

The published Linux benchmarks show ghostty-tip at a 965 ms mean keystroke latency. Bisecting shows this is a tip-only regression: 1.3.1 and the commit before upstream's GtkGLArea removal (ghostty-org/ghostty#14052) stay under 30 ms, while every later build sometimes draws a typed glyph only on the renderer's 600 ms cursor-blink tick. The published run had no ghostty release column to show that, and the run that reproduced it also found an instrument crash.

  • wl-latency waits out a full Wayland send buffer. blocking_dispatch and roundtrip flush before reading, and the flush returned WouldBlock on a loaded host, which panicked the leg and recorded it as the terminal's failure. Both calls now poll for writability and retry.
  • A full-field run refuses to start without both ghostty builds. The release had silently dropped out of the published run (its store path was most likely garbage-collected). --terminals still narrows a run.
  • The Linux bench shell pins ghostty's tip through a dev-partition input (FELIS_BENCH_GHOSTTY_TIP), so it no longer needs a hand fetch and is identified by the commit in dev/flake.lock, which lock maintenance advances. macOS keeps --tool.

Not included: republishing docs/reference/benchmarks.md with the release column; that waits for the next full run.

Verified: crossterm_test.py (240 tests), nix flake check --no-build, darwin bench-shell evaluation, and a latency run of 1.3.1 and tip through the rebuilt wl-latency.

The published Linux benchmarks show ghostty-tip at a 965 ms mean keystroke latency. Bisecting shows this is a tip-only regression: 1.3.1 and the commit before upstream's GtkGLArea removal (ghostty-org/ghostty#14052) stay under 30 ms, while every later build sometimes draws a typed glyph only on the renderer's 600 ms cursor-blink tick. The published run had no ghostty release column to show that, and the run that reproduced it also found an instrument crash. - **wl-latency waits out a full Wayland send buffer.** `blocking_dispatch` and `roundtrip` flush before reading, and the flush returned `WouldBlock` on a loaded host, which panicked the leg and recorded it as the terminal's failure. Both calls now poll for writability and retry. - **A full-field run refuses to start without both ghostty builds.** The release had silently dropped out of the published run (its store path was most likely garbage-collected). `--terminals` still narrows a run. - **The Linux bench shell pins ghostty's tip** through a dev-partition input (`FELIS_BENCH_GHOSTTY_TIP`), so it no longer needs a hand fetch and is identified by the commit in `dev/flake.lock`, which lock maintenance advances. macOS keeps `--tool`. Not included: republishing `docs/reference/benchmarks.md` with the release column; that waits for the next full run. Verified: `crossterm_test.py` (240 tests), `nix flake check --no-build`, darwin bench-shell evaluation, and a latency run of 1.3.1 and tip through the rebuilt wl-latency.
wayland-client's blocking_dispatch and roundtrip flush pending requests
before they read, and the flush returns WouldBlock instead of waiting
when the compositor has not drained the socket. The instrument treated
that as fatal, so on a loaded host a latency leg panicked mid-run
("dispatch: Backend(Io(... WouldBlock ...))") and was recorded as a
failure of the terminal under test. Both calls now poll the connection
for writability and retry; any other error still aborts.

Assisted-by: Claude Code:Opus 5.5
ghostty's release and its tip can disagree by two orders of magnitude:
on Linux, keystroke latency is about 10 ms on 1.3.1 and up to seconds
on tip, a regression that arrived with tip's GTK renderer rework. The
published Linux run carried only tip, because the release's pinned
store path had gone missing and the field silently dropped it, so the
page could not tell a tip-only regression from ghostty's own behavior.
A run over the full field now stops before measuring unless both
builds resolve; --terminals still narrows a run for iteration.

Assisted-by: Claude Code:Opus 5.5
bench: pin ghostty's tip in the Linux bench shell
All checks were successful
bench / Criterion full-suite snapshot (pull_request) Has been skipped
fuzz / cargo fuzz nightly long-run (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 53s
darwin / publish felis (aarch64-darwin) (pull_request) Has been skipped
fuzz / cargo fuzz smoke (per target) (pull_request) Successful in 1m3s
windows / frontend smoke (Windows) (pull_request) Successful in 1m37s
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been skipped
windows / cargo clippy (Windows cross) (pull_request) Successful in 12s
bench / Criterion regression gate (pull_request) Successful in 2m4s
darwin / detect relevant changes (pull_request) Successful in 4s
darwin / darwin docs-only no-op (pull_request) Has been skipped
pr / nix flake check (pull_request) Successful in 41s
pr / cargo build / clippy / test / deny (pull_request) Successful in 1m36s
pr / wire schema is compatible with the base (pull_request) Successful in 14s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 1m18s
pr / publish felis (x86_64-linux) (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 4s
windows / windows docs-only no-op (pull_request) Has been skipped
windows / cargo nextest (Windows) (pull_request) Successful in 4m4s
2162d8a432
A full-field run now needs both ghostty builds, and on Linux the tip was
the one a person had to fetch by hand before every run. Upstream's flake
builds it, so the dev partition takes it as an input and the bench shell
exports it as FELIS_BENCH_GHOSTTY_TIP. The tip is then a commit recorded
in dev/flake.lock rather than whatever was fetched that day, and lock
maintenance moves it forward.

This reverses the earlier stance that a lockfile-pinned nightly is not a
nightly: what the field needs is the unreleased code next to the release,
and a recorded commit identifies it better than a build that replaces
itself. macOS keeps --tool, since upstream's flake does not build there.
The input does not follow nixpkgs-dev because the tip compiles only with
the Zig upstream pins.

Assisted-by: Claude Code:Opus 5.5
natsukium deleted branch bench/wl-latency-wouldblock 2026-09-24 18:37:13 +09:00
Commenting is not possible because the repository is archived.
No description provided.