[vim/vim] Scrolling recomputes the height of every visible line (PR #21207)

4 views
Skip to first unread message

Julien Voisin

unread,
Sep 1, 2026, 11:20:05 AM (yesterday) Sep 1
to vim/vim, Subscribed

Problem: When scrolling, comp_botline() recomputes the display height of
every line in the window on each cursor movement, which is
slower than necessary.
Solution: Reuse the line heights computed for the previous redraw, stored
in w_lines[], the same way curs_rows() already does. (Julien Voisin)

comp_botline() computes w_botline by calling plines_correct_topline() for every line from the top (or cursor) to the bottom of the window. This walks every character of every line to measure its display width, and it runs on every scroll. When the display is up to date the heights are already known in w_lines[].wl_size and are equal to what plines() would return, so they can be reused, avoiding the per-line width computation. The cache is only trusted when redrawing, the buffer was not changed, no "$" is displayed and w_lines[] starts at or above w_topline; otherwise the previous computation is used.

Benchmark: 1500 real keystrokes sent to a terminal Vim scrolling a 60000-line syntax-highlighted C file in a 120x40 window. Instructions retired were measured with "perf stat", with the constant startup cost subtracted; run-to-run variation was under 0.01%.

                         instructions per key
command                 baseline    patched   change
j       (line down)       252883     117800    -53%
CTRL-E  (view down)       210580     114017    -46%
V then j  (visual)        320142     184959    -42%
CTRL-D  (half page)       634489     585040     -8%
CTRL-F  (full page)      1179034    1173068     -1%
k       (line up)           4289       4289      0%

The same test without syntax highlighting drops "j" from 217149 to 116598 instructions per key (-46%), and on a file of long wrapped lines from 374952 to 175579 (-53%).

The win scales with how much of the window is reused: a line- or view-scroll keeps all but one line, a half page keeps half, and a full page or an upward scroll reuse nothing, so those are unchanged.


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/21207

Commit Summary

  • 4d07684 Scrolling recomputes the height of every visible line

File Changes

(1 file)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/21207@github.com>

Christian Brabandt

unread,
2:53 PM (1 hour ago) 2:53 PM
to vim/vim, Subscribed
chrisbra left a comment (vim/vim#21207)

Thanks. I am slightly worried about the cache validation. When setting certain options like "folding", "diff", "number", "wrap", "breakindent" etc the rendering changes. Shouldn't we invalidate the cache in that case?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/21207/c5514698151@github.com>

Julien Voisin

unread,
3:52 PM (9 minutes ago) 3:52 PM
to vim/vim, Subscribed
jvoisin left a comment (vim/vim#21207)

I added a test to prove that nothing breaks :)


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/21207/c5515448823@github.com>

Reply all
Reply to author
Forward
0 new messages