perf(ansi): compare whole retained rows before scroll applicability checks
canApplyDenseScrollAgainst walked every retained cell through Frame.At. For full-width scrolls it now first compares the committed row (y+offset) with the target row via core.RowsEqualAt and only falls back to the per-cell damage coverage check for rows that differ.
- commit
- 1bbdfc6d77a80ff4974f8c71d6b9853c1544294e
- author
- brice · · 2026-10-02 09:47 UTC
- parent
- 748182f
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +7 -0
M ansi/scroll.go +7 -0
| @@ -3,6 +3,8 @@ package ansi | |||
| 3 | 3 | import ( | |
| 4 | 4 | "bytes" | |
| 5 | 5 | "strconv" | |
| 6 | + | ||
| 7 | + | "github.com/bnema/vev-vt/core" | |
| 6 | 8 | ) | |
| 7 | 9 | ||
| 8 | 10 | func findSafeScroll(frame CellSource, damage []Damage) (Damage, bool) { | |
| @@ -92,6 +94,11 @@ func canApplyScrollAgainst(frame CellSource, scroll Damage, damage []Damage, com | |||
| 92 | 94 | func canApplyDenseScrollAgainst(frame Frame, scroll Damage, damage []Damage, committed Frame) bool { | |
| 93 | 95 | start, end, offset := scrollRetainedRows(scroll) | |
| 94 | 96 | for y := start; y < end; y++ { | |
| 97 | + | // Scrolls are full width, so a retained row that matches whole needs no | |
| 98 | + | // per-cell damage lookups. | |
| 99 | + | if scroll.X == 0 && scroll.Width == frame.Width && core.RowsEqualAt(committed, y+offset, frame, y) { | |
| 100 | + | continue | |
| 101 | + | } | |
| 95 | 102 | for x := range scroll.Width { | |
| 96 | 103 | column := scroll.X + x | |
| 97 | 104 | committedCell, frameCell := committed.At(column, y+offset), frame.At(column, y) | |
| @@ -3,6 +3,8 @@ package ansi | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "bytes" | 4 | "bytes" | ||
| 5 | "strconv" | 5 | "strconv" | ||
| 6 | + | ||||
| 7 | + | "github.com/bnema/vev-vt/core" | |||
| 6 | ) | 8 | ) | ||
| 7 | 9 | ||||
| 8 | func findSafeScroll(frame CellSource, damage []Damage) (Damage, bool) { | 10 | func findSafeScroll(frame CellSource, damage []Damage) (Damage, bool) { | ||
| @@ -92,6 +94,11 @@ func canApplyScrollAgainst(frame CellSource, scroll Damage, damage []Damage, com | |||||
| 92 | func canApplyDenseScrollAgainst(frame Frame, scroll Damage, damage []Damage, committed Frame) bool { | 94 | func canApplyDenseScrollAgainst(frame Frame, scroll Damage, damage []Damage, committed Frame) bool { | ||
| 93 | start, end, offset := scrollRetainedRows(scroll) | 95 | start, end, offset := scrollRetainedRows(scroll) | ||
| 94 | for y := start; y < end; y++ { | 96 | for y := start; y < end; y++ { | ||
| 97 | + | // Scrolls are full width, so a retained row that matches whole needs no | |||
| 98 | + | // per-cell damage lookups. | |||
| 99 | + | if scroll.X == 0 && scroll.Width == frame.Width && core.RowsEqualAt(committed, y+offset, frame, y) { | |||
| 100 | + | continue | |||
| 101 | + | } | |||
| 95 | for x := range scroll.Width { | 102 | for x := range scroll.Width { | ||
| 96 | column := scroll.X + x | 103 | column := scroll.X + x | ||
| 97 | committedCell, frameCell := committed.At(column, y+offset), frame.At(column, y) | 104 | committedCell, frameCell := committed.At(column, y+offset), frame.At(column, y) | ||