Detect style run breaks via cheap CellStyleKey rather than full CellStyle comparison#208
Merged
Merged
Conversation
Collaborator
Author
|
Flaky test, as far as I can tell. |
…module When running profilers like Instruments to optimize Ghostel itself, you need debugging symbols and thus you need to build with -Doptimize=Debug. However, libghostty-vt is way too slow to get any useful data unless it's build in optimized release mode. This allows setting separate optimization levels.
…tyle comparison Replaces per-cell CellStyle.eql() with a two-field CellStyleKey (style_id + hyperlink) that is cheap to read and compare in the tight inner loop. The full readCellStyle call is deferred to run boundaries only. Default styles are represented as ?CellStyle = null, removing the isDefault() guard from applyStyle and the explicit "close final run" block. Wide-character spacer tails are compensated with end_char -= 1 to prevent boundary overcounting.
5cbb409 to
81f1258
Compare
Owner
|
Very nice. Thanks. BTW, if you want I can give you maintainer rights here on this repo. |
Collaborator
Author
|
@dakra I am indeed pretty invested by now and I'd love to have a chat about. I'll drop you an e-mail! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The hot inner loop in
buildRowContentpreviously calledreadCellStyleonevery terminal cell and compared the result field-by-field with
CellStyle.eql()across all ten style attributes (fg, bg, bold, italic, faint, underline,
underline_color, strikethrough, inverse, hyperlink).
This PR replaces that with a two-field
CellStyleKey(style_id+hyperlink)that is cheap to read and compare. The full
readCellStylecall is now deferredto run boundaries only — once per style change rather than once per cell.
style_idis Ghostty's unique identifier for a cell's complete attribute set.hyperlinkis tracked separately because Ghostty does not fold hyperlink stateinto the style ID, but Ghostel uses text properties for it.
Supporting changes:
RunInfo.stylebecomes?CellStyle(null = default style), removing theisDefault()guard fromapplyStyleand making the null check explicit atthe call site
end_char -= 1after the stylelogic runs, preventing boundary overcounting that would otherwise bleed style
from a styled wide character onto the following default-style cell
CellStyle.eql()is removed;std.meta.eqlonCellStyleKeyreplaces itBenchmark
All runs:
zig build -Doptimize=ReleaseFast, Elisp byte-compiled.Machine: Apple M5 Pro, macOS 26.4.1, Emacs 30.2.
Streaming (chunked write + periodic redraw, no PTY)
TUI frame rendering (full-screen rewrites)
TUI partial update (bottom-row update over static screen)
Engine micro-benchmarks (single bulk call, no PTY)
Real-world PTY (cat 1 MB through process pipe)
PTY improvements are modest: throughput there is dominated by process I/O and
timer overhead rather than per-cell render cost.