std::vec: Sane implementations for connect_vec and concat_vec
Avoid unnecessary copying of subvectors, and calculate the needed space beforehand. These implementations are simple but better than the previous. Also only implement it once, for all `Vector<T>` using: impl<'self, T: Clone, V: Vector<T>> VectorVector<T> for &'self [V] performance improved according to the bench test: before test vec::bench::concat ... bench: 74818 ns/iter (+/- 408) test vec::bench::connect ... bench: 87066 ns/iter (+/- 376) after test vec::bench::concat ... bench: 17724 ns/iter (+/- 126) test vec::bench::connect ... bench: 18353 ns/iter (+/- 691) Closes #9581
This commit is contained in:
parent
5444f601dc
commit
24a4d0daf0
@ -356,43 +356,32 @@ pub fn connect_slices<T:Clone>(v: &[&[T]], sep: &T) -> ~[T] { v.connect_vec(sep)
|
||||
pub trait VectorVector<T> {
|
||||
// FIXME #5898: calling these .concat and .connect conflicts with
|
||||
// StrVector::con{cat,nect}, since they have generic contents.
|
||||
/// Flattens a vector of vectors of T into a single vector of T.
|
||||
fn concat_vec(&self) -> ~[T];
|
||||
|
||||
/// Concatenate a vector of vectors, placing a given separator between each.
|
||||
fn connect_vec(&self, sep: &T) -> ~[T];
|
||||
}
|
||||
|
||||
impl<'self, T:Clone> VectorVector<T> for &'self [~[T]] {
|
||||
/// Flattens a vector of slices of T into a single vector of T.
|
||||
impl<'self, T: Clone, V: Vector<T>> VectorVector<T> for &'self [V] {
|
||||
fn concat_vec(&self) -> ~[T] {
|
||||
self.flat_map(|inner| (*inner).clone())
|
||||
}
|
||||
|
||||
/// Concatenate a vector of vectors, placing a given separator between each.
|
||||
fn connect_vec(&self, sep: &T) -> ~[T] {
|
||||
let mut r = ~[];
|
||||
let mut first = true;
|
||||
for inner in self.iter() {
|
||||
if first { first = false; } else { r.push((*sep).clone()); }
|
||||
r.push_all((*inner).clone());
|
||||
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
|
||||
let mut result = with_capacity(size);
|
||||
for v in self.iter() {
|
||||
result.push_all(v.as_slice())
|
||||
}
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self,T:Clone> VectorVector<T> for &'self [&'self [T]] {
|
||||
/// Flattens a vector of slices of T into a single vector of T.
|
||||
fn concat_vec(&self) -> ~[T] {
|
||||
self.flat_map(|&inner| inner.to_owned())
|
||||
result
|
||||
}
|
||||
|
||||
/// Concatenate a vector of slices, placing a given separator between each.
|
||||
fn connect_vec(&self, sep: &T) -> ~[T] {
|
||||
let mut r = ~[];
|
||||
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
|
||||
let mut result = with_capacity(size + self.len());
|
||||
let mut first = true;
|
||||
for &inner in self.iter() {
|
||||
if first { first = false; } else { r.push((*sep).clone()); }
|
||||
r.push_all(inner);
|
||||
for v in self.iter() {
|
||||
if first { first = false } else { result.push(sep.clone()) }
|
||||
result.push_all(v.as_slice())
|
||||
}
|
||||
r
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user