Skip to content

fix(diff-viewer): cache flattened search results for O(1) lookups - #620

Merged
matt2e merged 1 commit into
mainfrom
fix/diff-viewer-search-perf
Apr 14, 2026
Merged

fix(diff-viewer): cache flattened search results for O(1) lookups#620
matt2e merged 1 commit into
mainfrom
fix/diff-viewer-search-perf

Conversation

@matt2e

@matt2e matt2e commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Cache getFlattenedResults() output using identity checks on files array and fileResults map, avoiding O(total_matches) recomputation on every call
  • Build a Map<filePath, Map<localIndex, globalIndex>> lookup during flattening so getGlobalIndex() is O(1) instead of O(total_matches) linear .find()
  • Reduces per-render cost from O(3 * visible * total_matches) to O(1) per visible result (after initial O(total_matches) cache build)

Context

isCurrentResult() and getGlobalIndex() are called once each per visible search result during rendering in FileSearchResults.svelte. Both called getFlattenedResults() which rebuilds the entire flattened array every time, and getGlobalIndex additionally did a .find() linear scan. With 50 visible results and 500 total matches this caused ~75,000 iterations per render.

Test plan

  • Open the diff viewer and perform a search (Cmd+F or the search UI)
  • Verify search results highlight correctly in the file list and diff view
  • Verify "current result" indicator works when navigating with Enter/Shift+Enter
  • Verify the global result counter (e.g., "3 of 47") updates correctly
  • Verify clicking a search result navigates to the correct location
  • Verify "Show more" / "Show less" pagination still works
  • Verify search is responsive with many results across many files

🤖 Generated with Claude Code

…er cost

getFlattenedResults() was being called 3 times per visible search result
during rendering (once from isCurrentResult, twice from getGlobalIndex
including a linear .find()), causing O(visible × total_matches) work per
render. With 50 visible results and 500 total matches, this meant 75,000
iterations per render.

Now caches the flattened array and a filePath→localIndex→globalIndex
lookup Map, invalidated by identity checks on the inputs. getGlobalIndex
is now O(1) via Map lookup instead of O(T) linear search.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt2e
matt2e requested review from baxen and wesbillman as code owners April 14, 2026 04:19
@matt2e
matt2e merged commit 3b76b54 into main Apr 14, 2026
6 checks passed
@matt2e
matt2e deleted the fix/diff-viewer-search-perf branch April 14, 2026 05:01
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