mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-12-19 05:13:44 +08:00
Speed up get_case_fold() 5x
Using `c.is_uppercase()` instead of getting the iterator and checking if the first (and only) lowercase letter of the sequence is the same as the original input is 5-8x faster (measured via criterion against `/usr/share/dict/words`). (Additional benefit of forcibly inlining the now iterator-based comparison not taken into account; this necessitated changing from a closure to a local function as the inline attribute on closures is not yet supported with the stable compiler toolchain.)
This commit is contained in:
parent
b949497bc1
commit
8c8da78cf8
|
@ -175,14 +175,14 @@ impl StringFuzzyMatch {
|
||||||
) -> Option<StringFuzzyMatch> {
|
) -> Option<StringFuzzyMatch> {
|
||||||
// Helper to lazily compute if case insensitive matches should use icase or smartcase.
|
// Helper to lazily compute if case insensitive matches should use icase or smartcase.
|
||||||
// Use icase if the input contains any uppercase characters, smartcase otherwise.
|
// Use icase if the input contains any uppercase characters, smartcase otherwise.
|
||||||
let get_case_fold = || {
|
#[inline(always)]
|
||||||
for c in string.chars() {
|
fn get_case_fold(s: &widestring::Utf32Str) -> CaseSensitivity {
|
||||||
if c.to_lowercase().next().unwrap() != c {
|
if s.chars().any(|c| c.is_uppercase()) {
|
||||||
return CaseSensitivity::Insensitive;
|
CaseSensitivity::Insensitive
|
||||||
}
|
} else {
|
||||||
|
CaseSensitivity::Smart
|
||||||
}
|
}
|
||||||
CaseSensitivity::Smart
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// A string cannot fuzzy match against a shorter string.
|
// A string cannot fuzzy match against a shorter string.
|
||||||
if string.len() > match_against.len() {
|
if string.len() > match_against.len() {
|
||||||
|
@ -207,12 +207,18 @@ impl StringFuzzyMatch {
|
||||||
|
|
||||||
// exact icase
|
// exact icase
|
||||||
if wcscasecmp(string, match_against).is_eq() {
|
if wcscasecmp(string, match_against).is_eq() {
|
||||||
return Some(StringFuzzyMatch::new(ContainType::Exact, get_case_fold()));
|
return Some(StringFuzzyMatch::new(
|
||||||
|
ContainType::Exact,
|
||||||
|
get_case_fold(string),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefix icase
|
// prefix icase
|
||||||
if string_prefixes_string_case_insensitive(string, match_against) {
|
if string_prefixes_string_case_insensitive(string, match_against) {
|
||||||
return Some(StringFuzzyMatch::new(ContainType::Prefix, get_case_fold()));
|
return Some(StringFuzzyMatch::new(
|
||||||
|
ContainType::Prefix,
|
||||||
|
get_case_fold(string),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If anchor_start is set, this is as far as we go.
|
// If anchor_start is set, this is as far as we go.
|
||||||
|
@ -234,7 +240,10 @@ impl StringFuzzyMatch {
|
||||||
|
|
||||||
// substr icase
|
// substr icase
|
||||||
if ifind(match_against, string, true /* fuzzy */).is_some() {
|
if ifind(match_against, string, true /* fuzzy */).is_some() {
|
||||||
return Some(StringFuzzyMatch::new(ContainType::Substr, get_case_fold()));
|
return Some(StringFuzzyMatch::new(
|
||||||
|
ContainType::Substr,
|
||||||
|
get_case_fold(string),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// subseq samecase
|
// subseq samecase
|
||||||
|
|
Loading…
Reference in New Issue
Block a user