mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-12-18 20:53:40 +08:00
Reduce allocations when deduping completions in place
This is still suboptimal because we are allocating a vector of indices to be removed (but allocation-free in the normal case of no duplicates) but significantly better than the previous version of the code that duplicated the strings (which are larger and spread out all over the heap). The ideal code (similar to what we had in the C++ version, iirc) would look like this, but it's not allowed because the borrow checker hates you: ``` fn unique_in_place_illegal(comps: &mut Vec<Completion>) { let mut seen = HashSet::with_capacity(comps.len()); let mut idx = 0; while idx < comps.len() { if !seen.insert(&comps[idx].completion) { comps.remove(idx); continue; } idx += 1; } } ```
This commit is contained in:
parent
36c5ee045c
commit
b570c7f6a6
|
@ -512,14 +512,17 @@ fn compare_completions_by_tilde(a: &Completion, b: &Completion) -> Ordering {
|
|||
/// Unique the list of completions, without perturbing their order.
|
||||
fn unique_completions_retaining_order(comps: &mut Vec<Completion>) {
|
||||
let mut seen = HashSet::with_capacity(comps.len());
|
||||
let removals = comps.iter().enumerate().fold(vec![], |mut v, (i, c)| {
|
||||
if !seen.insert(&c.completion) {
|
||||
v.push(i);
|
||||
}
|
||||
v
|
||||
});
|
||||
|
||||
let pred = |c: &Completion| {
|
||||
// Keep (return true) if insertion succeeds.
|
||||
// todo!("don't clone here");
|
||||
seen.insert(c.completion.to_owned())
|
||||
};
|
||||
|
||||
comps.retain(pred);
|
||||
// Remove in reverse order so the indexes remain valid
|
||||
for idx in removals.iter().rev() {
|
||||
comps.remove(*idx);
|
||||
}
|
||||
}
|
||||
|
||||
/// Sorts and removes any duplicate completions in the completion list, then puts them in priority
|
||||
|
|
Loading…
Reference in New Issue
Block a user