Skip to content

Render no-wrap syntax directly#4181

Open
KRRT7 wants to merge 5 commits into
Textualize:mainfrom
KRRT7:perf/syntax-direct-no-wrap
Open

Render no-wrap syntax directly#4181
KRRT7 wants to merge 5 commits into
Textualize:mainfrom
KRRT7:perf/syntax-direct-no-wrap

Conversation

@KRRT7

@KRRT7 KRRT7 commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Optimizes Syntax(word_wrap=False, line_numbers=False) for non-transparent themes by rendering, cropping, and padding split Text lines directly instead of routing the highlighted text through Console.render_lines(...).

This stacks on #4179 and targets the remaining simple syntax rendering path that still used the generic render_lines pipeline.

Performance framing

Observed:
The simple no-wrap, no-line-number syntax path still used Console.render_lines(...) to crop and pad highlighted text.

Target:
Split the highlighted Text once, render each line directly, and use Segment.adjust_line_length(...) with the line base style for padding.

Hypothesis:
Avoiding the generic render_lines path should reduce overhead for large syntax blocks while preserving crop, padding, blank-line, trailing-newline, and theme-background behavior.

Target workload

User-visible operation: Console.print(Syntax(...)) for large Python syntax output without line wrapping or line numbers.

Workload:

code = snippets.PYTHON_SNIPPET * 120
syntax = Syntax(code=code, lexer="python", word_wrap=False, line_numbers=False)
console = Console(file=StringIO(), color_system="truecolor", legacy_windows=False, width=80)
console.print(syntax)

Environment:

  • Darwin arm64
  • Python 3.14.6
  • Pygments 2.20.0
  • pytest 9.0.3

Performance

Before, on #4179 tip before this change:

median: 0.474942s over 15 runs

After:

median: 0.427367s over 15 runs

This is about a 10.0% speedup for the target workload.

Correctness

python3 -m pytest tests/test_syntax.py tests/test_console.py
126 passed

uvx black --check rich/syntax.py benchmarks/benchmarks.py tests/test_syntax.py
3 files would be left unchanged

I also checked output preservation for cropped lines, blank middle lines, and trailing newlines, and smoke-tested the new ASV benchmark method:

SyntaxLargeNoWrapSuite.setup()
SyntaxLargeNoWrapSuite.time_text_wide_terminal_no_wrapping()

Tradeoffs

No new cache or retained state. This duplicates the small part of Console.render_lines(...) needed for this hot path: rendering split text lines, applying the configured background style, fixed-width adjustment, and newline emission.

Stack

Order PR Branch Merge after
1 #4177 optimize-syntax-word-wrap main
2 #4178 perf/syntax-line-numbers-word-wrap #4177
3 #4179 perf/syntax-direct-word-wrap #4178
4 #4181 perf/syntax-direct-no-wrap #4179

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@9d8f9a3). Learn more about missing BASE report.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4181   +/-   ##
=======================================
  Coverage        ?   97.81%           
=======================================
  Files           ?       96           
  Lines           ?     8391           
  Branches        ?        0           
=======================================
  Hits            ?     8208           
  Misses          ?      183           
  Partials        ?        0           
Flag Coverage Δ
unittests 97.81% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants