Skip to content

Memoize CharactersPerSecond and PixelWidth in SubtitleLineViewModel (grid binding perf)#11675

Closed
niksedk wants to merge 1 commit into
mainfrom
perf/subtitle-row-vm-memo
Closed

Memoize CharactersPerSecond and PixelWidth in SubtitleLineViewModel (grid binding perf)#11675
niksedk wants to merge 1 commit into
mainfrom
perf/subtitle-row-vm-memo

Conversation

@niksedk

@niksedk niksedk commented Jun 17, 2026

Copy link
Copy Markdown
Member

Optimizes two hot per-row bindings in the subtitle grid. Both getters on SubtitleLineViewModel are bound straight into grid cells, and Avalonia re-evaluates them on every cell repaint.

CharactersPerSecond is hit several times per row repaint — the CPS cell text binding, CpsBackgroundBrush, and the DurationBackgroundBrush SE4 fallback all read it, each running SubtitleTextInfoHelper.GetCharactersPerSecond.

PixelWidth shapes text with SkiaSharp (SKShaper.Shape) on every read and is consumed both by the pixel-width column and by TextBackgroundBrush's "too wide" check.

Change

Add value-keyed memoization:

  • CPS keyed on Text / StartTime / EndTime
  • PixelWidth keyed on Text + the configured width font name/size

The cache keys are the actual computation inputs, so it self-invalidates when any input changes — no reliance on PropertyChanged ordering, and behavior is identical. Repeated reads with unchanged inputs (the common case during repaint/scroll) reuse the result instead of recomputing.

🤖 Generated with Claude Code

Both getters are bound directly into subtitle-grid cells and Avalonia re-evaluates
them on every cell repaint:

- CharactersPerSecond is hit multiple times per row repaint (CPS cell text,
  CpsBackgroundBrush, and the DurationBackgroundBrush SE4 fallback), each running
  SubtitleTextInfoHelper.GetCharactersPerSecond.
- PixelWidth shapes text with SkiaSharp (SKShaper.Shape) and is read both by the
  pixel-width column and by TextBackgroundBrush.

Add value-keyed memoization (CPS keyed on Text/StartTime/EndTime; PixelWidth keyed
on Text + the width font name/size) so repeated reads with unchanged inputs reuse
the result. The keys are the actual inputs, so the cache self-invalidates without
relying on PropertyChanged ordering; behavior is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@niksedk niksedk closed this Jun 17, 2026
@niksedk niksedk deleted the perf/subtitle-row-vm-memo branch June 18, 2026 04:37
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.

1 participant