Expand description
Frizbee is a SIMD typo-resistant fuzzy string matcher written in Rust. The core of the algorithm uses Smith-Waterman with affine gaps, similar to FZF. In the included benchmark, with typo resistance disabled, it outperforms Nucleo by ~4x and FZF by ~5x and supports multithreading, see benchmarks. When matching against unicode, it outperforms Nucleo and FZF by 20x.
Used by blink.cmp, skim, and fff. Special thank you to stefanboca and ii14!
For commercial support, please contact me. I’d be happy to work with you directly! Also, please consider sponsoring me.
The core of the algorithm is Smith-Waterman with affine gaps and row-wise parallelism via SIMD. Besides the parallelism, this is the basis of other popular fuzzy matching algorithms like FZF and Nucleo. The main properties of Smith-Waterman are:
- Always finds the best alignment
- Supports insertion (unmatched char in haystack, basis of fuzzy matching)
- Supports deletion (unmatched char in needle, basis of typo-resistance)
- Supports substitution (haystack and needle char mismatch, basis of typo-resistance)
§Example: using match_list
use neo_frizbee::{match_list, match_list_parallel, Config};
let needle = "fBr";
let haystacks = ["fooBar", "foo_bar", "prelude", "println!"];
let matches = match_list(needle, &haystacks, &Config::default());
// or in parallel (8 threads)
let matches = match_list_parallel(needle, &haystacks, &Config::default(), 8);§Example: using Matcher
Useful for when you want to match one needle against more than one haystack.
use neo_frizbee::{Matcher, Config};
let needle = "fBr";
let haystacks = ["fooBar", "foo_bar", "prelude", "println!"];
let mut matcher = Matcher::new(needle, &Config::default());
let matches = matcher.match_list(&haystacks);§Example: using FuzzyMatchExt
use neo_frizbee::{iter::FuzzyMatchExt, Config, radix_sort_matches};
let haystacks = ["fooBar", "foo_bar", "prelude", "println!"];
let mut matches: Vec<_> = haystacks
.iter()
.fuzzy_match("fBr", &Config::default())
.collect();
radix_sort_matches(&mut matches);Modules§
- iter
- Iterator extension for fuzzy matching
Structs§
Enums§
Constants§
- SIMD_
CHUNK_ BYTES - Chunk width in bytes for the resolver-based matching APIs
(
crate::match_list_parallel_resolved). Haystacks are provided as lists of pointers to chunks of this size, with the last chunk zero-padded.
Functions§
- k_
merge_ matches - Merges multiple pre-sorted runs of
Matches into a single sortedVec. - match_
list - Matches a list of haystacks, returning a list of
Matchvalues. This API provides the most performant path when matching on lists. - match_
list_ indices - Matches a list of haystacks, returning a list of
MatchIndiceswhich are equivalent toMatchexcept they include the indices of the matched characters in the haystack. - match_
list_ parallel - Matches a list of haystacks in parallel on multiple real threads, returning a list of
Matchvalues. Threads work on 2048 item chunks, which are sorted and merged into a single sortedVecat the end. Thethreadsmust be >0. - match_
list_ parallel_ resolved - Matches items in parallel on multiple real threads, resolving each item’s haystack bytes
through the
resolvecallback, returning a list ofMatchvalues. Threads work on 2048 item chunks, which are sorted and merged into a single sortedVecat the end. Thethreadsmust be >0. - radix_
sort_ matches - Sorts a slice of
Matchvalues in-place by descendingscoreusing a stable radix sort. This assumes that the matches are already sorted by index.