Skip to content

Commit

Permalink
Be much less clever about things
Browse files Browse the repository at this point in the history
This one only helps lower>0, but by doing so means it's always strictly less than 100% overhead, same as the normal doubling algorithm.  And thus doesn't need to do the try_reserve dance or a post-extend cleanup.
  • Loading branch information
scottmcm committed Aug 8, 2018
1 parent d545902 commit aa080f4
Showing 1 changed file with 6 additions and 25 deletions.
31 changes: 6 additions & 25 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1861,36 +1861,17 @@ impl<T, I> SpecExtend<T, I> for Vec<T>
if let Some(x) = iterator.next() { x }
else { return Vec::new() };
let (lower, upper) = iterator.size_hint();
let upper = upper.unwrap_or(lower);
let mut vector =
if lower >= upper / 2 {
// This branch covers three main cases:
// - There was no upper bound, so we just use the lower.
// - The hint turned out to be exact, so we use it.
// - Picking the upper won't waste more that the doubling
// strategy might anyway, so go directly there.
Vec::with_capacity(upper.saturating_add(1))
} else {
// Try to start near the geometric mean of the range. That's
// never all that high -- even 0B..1GB will only allocate 32kB --
// but it's much more useful than the lower bound, especially
// for iterator adapters like filter that have lower == 0.
let mut v = Vec::new();
let mag_diff = lower.leading_zeros() - upper.leading_zeros();
let guess = upper >> (mag_diff / 2);
match v.try_reserve(guess.saturating_add(1)) {
Ok(_) => v,
Err(_) => Vec::with_capacity(lower.saturating_add(1)),
}
};
let guess = if let Some(upper) = upper {
lower.saturating_mul(2).min(upper)
} else {
lower
};
let mut vector = Vec::with_capacity(guess.saturating_add(1));
unsafe {
ptr::write(vector.get_unchecked_mut(0), element);
vector.set_len(1);
}
<Vec<T> as SpecExtend<T, I>>::spec_extend(&mut vector, iterator);
if vector.len() < vector.capacity() / 2 {
vector.shrink_to_fit();
}
vector
}

Expand Down

0 comments on commit aa080f4

Please sign in to comment.