SIGN IN SIGN UP

perf: resolve canonical paths and build the matcher once

Typing in the picker got slower as the index grew. Two hot paths were
doing per-comparison and per-candidate work that only needs doing once.

`Entry::key()` called `fs::canonicalize` on every invocation, and
`apply_filter`'s comparator reached it twice per comparison through
`is_pinned` -> `pin_key`. Sorting n entries therefore issued roughly
2n*log2(n) syscalls per keystroke, whether or not any pins existed.

`match_score` constructed a fresh `NucleoMatcher` and re-parsed the
search `Pattern` inside the per-entry loop, rebuilding both once per
candidate per keystroke.

- Cache the resolved path per entry in a `OnceLock<String>`; `key()` now
  returns `&str` and canonicalizes at most once per entry. Entries are
  rebuilt by `refresh()`, so the cache cannot outlive its source data.
- Resolve each candidate's sort keys (pins, score, source rank) during
  the filter scan and sort over those, leaving the comparator free of
  filesystem access.
- Replace `match_score` with a `Scorer` prepared once per query.

Measured on a 2660-entry index (2640 from zoxide) on ext4: ~338 ms of
canonicalize per keystroke before, ~0 after the first pass. Ordering is
unchanged; the comparator applies the same keys in the same sequence.

Fixes #22
A
AnnanKhan committed
8ea90008d6edf0ae0865dbcfdfd001241b6a680b
Parent: ccacb21