perf: early exit in count_tail_present_ordered when match is impossible

Add a hopeless-state check at the top of each iteration: if matched
plus remaining pattern chars cannot reach min_needed, bail out
immediately rather than completing the full scan.

This prunes the non-ASCII (char) ordered-scan fallback inside
cheap_typo_prefilter when the pattern is long and many chars are
missing from the choice.
This commit is contained in:
Loric ANDRE 2026-02-26 15:50:37 +01:00
parent d79947fcb5
commit 29721558f0

View file

@ -607,12 +607,25 @@ impl SkimV3Matcher {
/// available (e.g. non-ASCII input). Pattern cursors reset on miss so that
/// subsequent pattern chars can still match even when a middle char is absent
/// (typo-tolerant semantics).
///
/// Early-exit: if the remaining choice positions plus already-matched chars
/// cannot reach `min_needed`, the scan terminates immediately.
#[inline]
fn count_tail_present_ordered<C: Atom>(pat_tail: &[C], choice: &[C], respect_case: bool, min_needed: usize) -> usize {
let m = choice.len();
let n_tail = pat_tail.len();
let mut matched = 0usize;
let mut ci = 0usize;
for &pi in pat_tail {
for (pi_idx, &pi) in pat_tail.iter().enumerate() {
// If matched + remaining pattern chars can't reach min_needed, give up.
let remaining_pat = n_tail - pi_idx;
if matched + remaining_pat < min_needed {
return matched;
}
// If no choice chars remain, stop.
if ci >= m {
return matched;
}
let ci_save = ci;
let mut found = false;
while ci < m {