Skip to content

Commit d6715e6

Browse files
committed
shuf: Reduce malloc
1 parent 1e95554 commit d6715e6

1 file changed

Lines changed: 10 additions & 8 deletions

File tree

src/uu/shuf/src/nonrepeating_iterator.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// hijack HashMap for performance
2-
type HashMap<K, V> = std::collections::HashMap<K, V, rustc_hash::FxBuildHasher>;
3-
1+
use rustc_hash::FxHashMap;
42
use std::ops::RangeInclusive;
53

64
use uucore::error::UResult;
@@ -42,12 +40,17 @@ pub(crate) struct NonrepeatingIterator<'a> {
4240

4341
enum Values {
4442
Full(Vec<u64>),
45-
Sparse(RangeInclusive<u64>, HashMap<u64, u64>),
43+
Sparse(RangeInclusive<u64>, FxHashMap<u64, u64>),
4644
}
4745

4846
impl<'a> NonrepeatingIterator<'a> {
4947
pub(crate) fn new(range: RangeInclusive<u64>, rng: &'a mut WrappedRng) -> Self {
50-
let values = Values::Sparse(range, HashMap::default());
48+
let avoid_reallocation_bound = 128; // todo: optimize this
49+
let capacity = (range.size_hint().0).min(avoid_reallocation_bound);
50+
let values = Values::Sparse(
51+
range,
52+
FxHashMap::with_capacity_and_hasher(capacity, rustc_hash::FxBuildHasher),
53+
);
5154
NonrepeatingIterator { rng, values }
5255
}
5356

@@ -96,8 +99,7 @@ impl Iterator for NonrepeatingIterator<'_> {
9699
Values::Full(_) => (),
97100
Values::Sparse(range, _) if range.is_empty() => return None,
98101
Values::Sparse(range, items) => {
99-
let range_len = range.size_hint().0 as u64;
100-
if items.len() as u64 >= range_len / 8 {
102+
if items.len() as u64 >= items.capacity() as u64 {
101103
self.values = Values::Full(hashmap_to_vec(range.clone(), items));
102104
}
103105
}
@@ -107,7 +109,7 @@ impl Iterator for NonrepeatingIterator<'_> {
107109
}
108110
}
109111

110-
fn hashmap_to_vec(range: RangeInclusive<u64>, map: &HashMap<u64, u64>) -> Vec<u64> {
112+
fn hashmap_to_vec(range: RangeInclusive<u64>, map: &FxHashMap<u64, u64>) -> Vec<u64> {
111113
let lookup = |idx| *map.get(&idx).unwrap_or(&idx);
112114
range.rev().map(lookup).collect()
113115
}

0 commit comments

Comments
 (0)