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.
This commit is contained in:
Roo Code 2026-01-06 14:55:11 +00:00
parent 861139ca24
commit 4ce4acd73b
2 changed files with 22 additions and 0 deletions

View file

@ -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++
}

View file

@ -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++
}