Skip to content

Paint unified diff decorations only for the damaged lines - #2897

Open
vogella wants to merge 1 commit into
eclipse-platform:masterfrom
vogella:unified-diff-paint-visible-only
Open

Paint unified diff decorations only for the damaged lines#2897
vogella wants to merge 1 commit into
eclipse-platform:masterfrom
vogella:unified-diff-paint-visible-only

Conversation

@vogella

@vogella vogella commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

The unified diff paint listener asked StyledText for the bounds of every line of every hunk on each repaint, on-screen or not. Because the overlay puts the widget into variable line height mode, each of those queries lays out lines that are never shown, so a repaint costs O(document) and a large file with many hunks becomes unusable: on a 1.7 MB file, opening a diff blocked the UI for seconds and every page scroll for a good part of a second.

The paint listener now clips its loop to the lines inside the paint event's damaged rectangle, so a repaint is proportional to what is visible. The line header code mining additionally resolves the line range of each detailed diff once when the mining is created, off the UI thread, instead of re-deriving it from copies of the hunk text while drawing.

Verified in a running SDK against the same file with 251 hunks: the paint listener no longer appears in the UI thread profile at all (previously 29 samples across open, 8 page scrolls and one edit), and the UI block per 8 page scrolls dropped from 125 ms to 3 ms on Linux/GTK. UnifiedDiffManagerTest and UnifiedDiffTextTest pass.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Test Results

    54 files  ±0      54 suites  ±0   57m 54s ⏱️ +59s
 4 767 tests +1   4 745 ✅ +1   22 💤 ±0  0 ❌ ±0 
12 192 runs  +3  12 039 ✅ +3  153 💤 ±0  0 ❌ ±0 

Results for commit 05f922c. ± Comparison against base commit 241fa27.

♻️ This comment has been updated with latest results.

@vogella
vogella force-pushed the unified-diff-paint-visible-only branch from c922697 to b8c918d Compare September 4, 2026 07:52

@tobiasmelcher tobiasmelcher left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks a lot Lars

The unified diff paint listener queried StyledText for the bounds of
every line of every hunk on each repaint. With inlined annotations the
widget has variable line heights, so each query lays out lines that are
not on screen, and a repaint costs O(document): on a 1.7 MB file opening
a diff blocked the UI for seconds and each page scroll for a good part
of a second.

Clip the loop to the lines inside the paint event's damaged rectangle,
so a repaint is proportional to what is visible.

The line header code mining also re-derived the line range of every
detailed diff from copies of the hunk text while drawing. Resolve these
ranges once when the mining is created, off the UI thread, and reuse the
split lines and Document across the detailed diffs of one hunk.

Assisted-by: multiple AI agents and layers of automated tooling 🤖
@vogella
vogella force-pushed the unified-diff-paint-visible-only branch from b8c918d to 05f922c Compare September 4, 2026 16:04
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