docs: publish the Linux cross-terminal benchmark results #374
No reviewers
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis!374
Loading…
Reference in a new issue
No description provided.
Delete branch "docs/linux-benchmarks"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds a Linux run to
docs/reference/benchmarks.mdnext to the existing macOS run: three rounds on an Inteli5-12400F + RTX 3080 under niri, against kitty 0.49.0 (nixpkgs master), alacritty, wezterm, ghostty tip and foot.
The macOS content moves under its own
## macOSheading, and each platform's charts get their own directory.Two harness fixes found while measuring:
bench: key chart colors by terminal— a chart missing one terminal shifted every hue, so kitty was drawn infelis's blue.
bench: require the niri pin to hold for a second— ghostty tip applied a stale resize after the pin reportedsuccess, and three of its legs ran at 106x7.
Open question before merging
felis's window stops repainting under sustained output on this machine. Run alone under DOOM-fire it showed no
frame for 16 s while DOOM-fire reported 1,680 fps, and it stalled partway through termbench-pro. The page drops
felis's DOOM-fire result and states that its Linux throughput figures are upper bounds. Either merge with that caveat,
or fix the renderer first and re-measure felis.
Left out of the tables
trueas its child, foot exits without mapping a window, so hyperfine times no window.discarded. The
niri.pyfix is not yet exercised by a live run.Checks
python3 tools/bench/crossterm_test.py: 204 tests pass.just docs-links, prose check, treefmt: pass.Tracked in #375: the page drops felis's Linux DOOM-fire result and marks its throughput figures as upper bounds until that is fixed.
ghostty tip failed every Linux latency round ("no row carries 5 evenly spaced marks"). Driven by hand under niri on an RTX 3080, the cause is its presentation, not its input: with the reference pattern written straight to the pty (no keyboard involved) the first capture that holds all five glyphs arrives anywhere from 30 ms to 1.85 s later. Frames captured in between are partly drawn (glyphs and the bar cursor with rows missing) and are replaced only on redraws about 600 ms apart. ghostty 1.3.1 and kitty show the whole pattern within 40 ms under the same test, and ghostty tip with GSK_RENDERER=cairo does too, so it is the GL path of that build. Three instrument steps read the screen once, at a fixed moment, and so turned that slow presentation into a failure rather than a number: - Pattern detection captured once, 300 ms after typing (Typometer's constant). It now polls from 300 ms until the pattern is located or ANSWER_TIMEOUT runs out, and logs how long it took. - The key was held until its glyph showed, as upstream does. A Wayland client repeats a held key itself, so a glyph slower than the seat's repeat delay typed a second period into the next cell, which the next sample then read as a block cursor. The key is now released right after the press; terminals act on the press, and the other five terminals measure the same with either (alacritty 4.3-6.0 ms mean, foot 2.9). - A cell that is not background before its key used to abort as a block cursor. It is now waited out up to ANSWER_TIMEOUT and counted (`covered_before_key` in the JSON); a real block cursor never clears and still fails the leg. With these, ghostty tip completes 100-key legs at 190-315 ms mean and a maximum of 1.81 s, which is what its screen shows. Two further changes target the one alacritty round that failed with "the line would not clear" and that 40 relaunches (including right after a closing kitty window, the order that round ran in) did not reproduce. That round located its pattern one pixel row lower than every other alacritty leg, which is what a window still settling from its pin would produce. The "before" capture is now taken only once two captures 100 ms apart agree, and a deletion that does not read back resends the backspaces once (an erase at the start of a canonical-mode line is ignored, so this only recovers a lost key). A deletion that still fails now names the pixel it read, the background it expected, and whether niri moved the window since it was located. Assisted-by: Claude Code:Opus 5.5 Assisted-by: Claude Codea2997aa65275d0863035