From 4ce4acd73bc7a89626c29138ef144e5cdae1baa2 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Tue, 6 Jan 2026 14:55:11 +0000 Subject: [PATCH] perf: add early termination to fuzzySearch for CPU optimization Fixes #9750 Added early termination optimization to the fuzzySearch function in both multi-search-replace.ts and multi-file-search-replace.ts. When a perfect match (similarity === 1) is found, the search now returns immediately instead of continuing to iterate through all positions. This optimization significantly reduces CPU usage when exact matches are found early in the search, avoiding unnecessary Levenshtein distance calculations which are O(m*n) per comparison. --- src/core/diff/strategies/multi-file-search-replace.ts | 11 +++++++++++ src/core/diff/strategies/multi-search-replace.ts | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/core/diff/strategies/multi-file-search-replace.ts b/src/core/diff/strategies/multi-file-search-replace.ts index 1236a98fbb..9740a88447 100644 --- a/src/core/diff/strategies/multi-file-search-replace.ts +++ b/src/core/diff/strategies/multi-file-search-replace.ts @@ -32,6 +32,9 @@ function getSimilarity(original: string, search: string): number { /** * Performs a "middle-out" search of `lines` (between [startIndex, endIndex]) to find * the slice that is most similar to `searchChunk`. Returns the best score, index, and matched text. + * + * Performance optimization: Returns immediately when a perfect match (similarity === 1) is found, + * avoiding unnecessary Levenshtein distance calculations which are O(m*n) per comparison. */ function fuzzySearch(lines: string[], searchChunk: string, startIndex: number, endIndex: number) { let bestScore = 0 @@ -54,6 +57,10 @@ function fuzzySearch(lines: string[], searchChunk: string, startIndex: number, e bestScore = similarity bestMatchIndex = leftIndex bestMatchContent = originalChunk + // Early termination: perfect match found, no need to continue searching + if (similarity === 1) { + return { bestScore, bestMatchIndex, bestMatchContent } + } } leftIndex-- } @@ -66,6 +73,10 @@ function fuzzySearch(lines: string[], searchChunk: string, startIndex: number, e bestScore = similarity bestMatchIndex = rightIndex bestMatchContent = originalChunk + // Early termination: perfect match found, no need to continue searching + if (similarity === 1) { + return { bestScore, bestMatchIndex, bestMatchContent } + } } rightIndex++ } diff --git a/src/core/diff/strategies/multi-search-replace.ts b/src/core/diff/strategies/multi-search-replace.ts index a6a9913203..ed1ecfcc08 100644 --- a/src/core/diff/strategies/multi-search-replace.ts +++ b/src/core/diff/strategies/multi-search-replace.ts @@ -35,6 +35,9 @@ function getSimilarity(original: string, search: string): number { /** * Performs a "middle-out" search of `lines` (between [startIndex, endIndex]) to find * the slice that is most similar to `searchChunk`. Returns the best score, index, and matched text. + * + * Performance optimization: Returns immediately when a perfect match (similarity === 1) is found, + * avoiding unnecessary Levenshtein distance calculations which are O(m*n) per comparison. */ function fuzzySearch(lines: string[], searchChunk: string, startIndex: number, endIndex: number) { let bestScore = 0 @@ -55,6 +58,10 @@ function fuzzySearch(lines: string[], searchChunk: string, startIndex: number, e bestScore = similarity bestMatchIndex = leftIndex bestMatchContent = originalChunk + // Early termination: perfect match found, no need to continue searching + if (similarity === 1) { + return { bestScore, bestMatchIndex, bestMatchContent } + } } leftIndex-- } @@ -66,6 +73,10 @@ function fuzzySearch(lines: string[], searchChunk: string, startIndex: number, e bestScore = similarity bestMatchIndex = rightIndex bestMatchContent = originalChunk + // Early termination: perfect match found, no need to continue searching + if (similarity === 1) { + return { bestScore, bestMatchIndex, bestMatchContent } + } } rightIndex++ }