Skip to content

Commit

Permalink
std::vec: Sane implementations for connect_vec and concat_vec
Browse files Browse the repository at this point in the history
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
  • Loading branch information
blake2-ppc committed Sep 28, 2013
1 parent 5444f60 commit 24a4d0d
Showing 1 changed file with 15 additions and 26 deletions.
41 changes: 15 additions & 26 deletions src/libstd/vec.rs
Expand Up @@ -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];
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.
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());
}
r
}
fn connect_vec(&self, sep: &T) -> ~[T];
}

impl<'self,T:Clone> VectorVector<T> for &'self [&'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.to_owned())
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())
}
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
}
}

Expand Down

0 comments on commit 24a4d0d

Please sign in to comment.