Repository navigation
terminal: print repeated characters through printSlice - #13625
Merged
Merged
Conversation
While doing some work on my tmux fork I noticed multiple parts of libghostty-vt was slower than tmux equivalents(isolated). Turns out they do some smart stuff there. printRepeat called print() once per repeat, so something like \x1b[2000b ran grapheme checks, width lookups, wrap handling, etc etc 2000 times. printSlice is already documented as semantically identical to calling print per codepoint, so this just feeds the repeated codepoint through it in 4096-entry stack chunks. Simple runs take the batched fast path, and anything that needs care falls back to the previous behaviour.
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.
printRepeat(CSIb, repeat the previous character N times) callsprint()once per repeat, so something like\x1b[2000bran grapheme checks, width lookups, wrap handling, and the integrity assert 2000 times for what is usually the same character on the same row.Terminal.printwas 24% of samples on a REP-heavy micro benchmark.This PR just aims to add a fast path by introducing a chunking mechanism. anything that needs care (insert mode, grapheme clustering, hyperlinks) still falls back to per-codepoint print() inside printSlice, so behavior should stay unchanged.
Some profiling data:
Generated with some plain stupid logic:
macOS (hyperfine, 15 runs, warmup 3):
And now the really interesting and promising stuff
Linux, 24-core NixOS x86_64 (poop, 6s sampling):