diff options
| author | blake2-ppc <blake2-ppc> | 2013-09-28 04:15:40 +0200 |
|---|---|---|
| committer | blake2-ppc <blake2-ppc> | 2013-09-28 05:25:18 +0200 |
| commit | 24a4d0daf0ba954b94eeeb9eb83355cd2f16ede5 (patch) | |
| tree | ddff72104b11d337f2f89106067193c544e3ab7f /src/libstd | |
| parent | 5444f601dc02cd9f5fc886f438ea60310f664cc6 (diff) | |
| download | rust-24a4d0daf0ba954b94eeeb9eb83355cd2f16ede5.tar.gz rust-24a4d0daf0ba954b94eeeb9eb83355cd2f16ede5.zip | |
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
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/vec.rs | 41 |
1 files changed, 15 insertions, 26 deletions
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index ef4f508282c..4d7d4bffdf1 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -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 } } |
