Fuzzy match performance improvements redo (#22561)

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2025-01-01 22:31:06 -07:00 committed by GitHub
parent 28d1d2d939
commit 665717da9a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 89 additions and 96 deletions

View file

@ -8,7 +8,6 @@ pub mod test;
use anyhow::{anyhow, Context as _, Result};
use futures::Future;
use itertools::Either;
use regex::Regex;
use std::sync::{LazyLock, OnceLock};
@ -111,6 +110,28 @@ where
}
}
pub fn truncate_to_bottom_n_sorted_by<T, F>(items: &mut Vec<T>, limit: usize, compare: &F)
where
F: Fn(&T, &T) -> Ordering,
{
if limit == 0 {
items.truncate(0);
}
if items.len() <= limit {
items.sort_by(compare);
return;
}
// When limit is near to items.len() it may be more efficient to sort the whole list and
// truncate, rather than always doing selection first as is done below. It's hard to analyze
// where the threshold for this should be since the quickselect style algorithm used by
// `select_nth_unstable_by` makes the prefix partially sorted, and so its work is not wasted -
// the expected number of comparisons needed by `sort_by` is less than it is for some arbitrary
// unsorted input.
items.select_nth_unstable_by(limit, compare);
items.truncate(limit);
items.sort_by(compare);
}
#[cfg(unix)]
pub fn load_shell_from_passwd() -> Result<()> {
let buflen = match unsafe { libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) } {
@ -734,6 +755,29 @@ mod tests {
assert_eq!(vec, &[1000, 101, 21, 19, 17, 13, 9, 8]);
}
#[test]
fn test_truncate_to_bottom_n_sorted_by() {
let mut vec: Vec<u32> = vec![5, 2, 3, 4, 1];
truncate_to_bottom_n_sorted_by(&mut vec, 10, &u32::cmp);
assert_eq!(vec, &[1, 2, 3, 4, 5]);
vec = vec![5, 2, 3, 4, 1];
truncate_to_bottom_n_sorted_by(&mut vec, 5, &u32::cmp);
assert_eq!(vec, &[1, 2, 3, 4, 5]);
vec = vec![5, 2, 3, 4, 1];
truncate_to_bottom_n_sorted_by(&mut vec, 4, &u32::cmp);
assert_eq!(vec, &[1, 2, 3, 4]);
vec = vec![5, 2, 3, 4, 1];
truncate_to_bottom_n_sorted_by(&mut vec, 1, &u32::cmp);
assert_eq!(vec, &[1]);
vec = vec![5, 2, 3, 4, 1];
truncate_to_bottom_n_sorted_by(&mut vec, 0, &u32::cmp);
assert!(vec.is_empty());
}
#[test]
fn test_iife() {
fn option_returning_function() -> Option<()> {