Skip to content

terminal: print repeated characters through printSlice - #13625

Merged
mitchellh merged 1 commit into
ghostty-org:mainfrom
Uzaaft:perf/terminal-rep-batch-fill
Aug 5, 2026
Merged

mitchellh merged 1 commit into
ghostty-org:mainfrom
Uzaaft:perf/terminal-rep-batch-fill

Conversation

@Uzaaft

@Uzaaft Uzaaft commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

printRepeat (CSI b, repeat the previous character N times) calls print() once per repeat, so something like \x1b[2000b ran grapheme checks, width lookups, wrap handling, and the integrity assert 2000 times for what is usually the same character on the same row.

Terminal.print was 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:

D = "benchdata"
parts, total = [], 0
while total < 40_000_000:
    line = "x" + "\x1b[80b" + "y" + "\x1b[35b" + "\r\n"
    parts.append(line); total += len(line)
open(f"{D}/rep.bin", "wb").write("".join(parts).encode())

macOS (hyperfine, 15 runs, warmup 3):

mean
before 2.360 s
after 1.166 s

And now the really interesting and promising stuff

Linux, 24-core NixOS x86_64 (poop, 6s sampling):

wall_time instructions branch_misses peak_rss
before 1.51 s 50.9 G 9.41 M 6.82 MB
after 562 ms 9.07 G 114 K 6.74 MB

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.
@Uzaaft
Uzaaft requested a review from a team as a code owner August 5, 2026 13:44
@ghostty-bot ghostty-bot Bot added the vt Control sequence related label Aug 5, 2026
@mitchellh
mitchellh merged commit 3f8b99b into ghostty-org:main Aug 5, 2026
96 checks passed
@github-actions github-actions Bot added this to the 1.4.0 milestone Aug 5, 2026
@Uzaaft
Uzaaft deleted the perf/terminal-rep-batch-fill branch August 5, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

vt Control sequence related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants