From 25d6cd75eb72b684f9daa0ada1c8b8a4c0eba00a Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sat, 12 Sep 2026 18:36:47 -0700 Subject: [PATCH] perf(cmd-j): scan phrase word boundaries monotonically (#20282) --- .../palette-match/palette-assignment-ranking.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/lib/palette-match/palette-assignment-ranking.ts b/src/renderer/src/lib/palette-match/palette-assignment-ranking.ts index 64b9bb76b7a..202beb7c84b 100644 --- a/src/renderer/src/lib/palette-match/palette-assignment-ranking.ts +++ b/src/renderer/src/lib/palette-match/palette-assignment-ranking.ts @@ -34,10 +34,23 @@ function phrasePlacement(field: PaletteIndexedField, normalizedQuery: string): n if (text.startsWith(normalizedQuery)) { return 0 } - for (const word of field.words) { - if (text.startsWith(normalizedQuery, word.start)) { + // Merge the ordered occurrence and word-start streams: occurrences only count at word + // starts, so each side advances monotonically and never rescans the other. + let index = text.indexOf(normalizedQuery, 1) + let wordIndex = 0 + while (index !== -1) { + let wordStart = field.words[wordIndex]?.start + while (wordStart !== undefined && wordStart < index) { + wordIndex += 1 + wordStart = field.words[wordIndex]?.start + } + if (wordStart === undefined) { + break + } + if (wordStart === index) { return 1 } + index = text.indexOf(normalizedQuery, wordStart) } return 2 }