Skip to content

Commit c635fba

Browse files
committed
auto merge of rust-lang#9583 : blake2-ppc/rust/connect-vec, r=huonw
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] Closes rust-lang#9581
2 parents 058a5d9 + 3709aa7 commit c635fba

File tree

3 files changed

+45
-54
lines changed

3 files changed

+45
-54
lines changed

src/librustc/middle/check_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -773,12 +773,12 @@ pub fn specialize(cx: &MatchCheckCtxt,
773773
let num_elements = before.len() + after.len();
774774
if num_elements < arity && slice.is_some() {
775775
Some(vec::append(
776-
vec::concat(&[
776+
[
777777
before,
778778
vec::from_elem(
779779
arity - num_elements, wild()),
780780
after
781-
]),
781+
].concat_vec(),
782782
r.tail()
783783
))
784784
} else if num_elements == arity {

src/librustdoc/clean.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,11 @@ impl Clean<Item> for doctree::Module {
173173
visibility: self.vis.clean(),
174174
id: self.id,
175175
inner: ModuleItem(Module {
176-
items: std::vec::concat(&[self.structs.clean(),
177-
self.enums.clean(), self.fns.clean(),
178-
std::vec::concat(self.foreigns.clean()),
179-
self.mods.clean(), self.typedefs.clean(),
180-
self.statics.clean(), self.traits.clean(),
181-
self.impls.clean(), self.view_items.clean()])
176+
items: [self.structs.clean(), self.enums.clean(),
177+
self.fns.clean(), self.foreigns.clean().concat_vec(),
178+
self.mods.clean(), self.typedefs.clean(),
179+
self.statics.clean(), self.traits.clean(),
180+
self.impls.clean(), self.view_items.clean()].concat_vec()
182181
})
183182
}
184183
}

src/libstd/vec.rs

+38-46
Original file line numberDiff line numberDiff line change
@@ -340,59 +340,36 @@ pub fn flat_map<T, U>(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] {
340340
result
341341
}
342342

343-
/// Flattens a vector of vectors of T into a single vector of T.
344-
pub fn concat<T:Clone>(v: &[~[T]]) -> ~[T] { v.concat_vec() }
345-
346-
/// Concatenate a vector of vectors, placing a given separator between each
347-
pub fn connect<T:Clone>(v: &[~[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
348-
349-
/// Flattens a vector of vectors of T into a single vector of T.
350-
pub fn concat_slices<T:Clone>(v: &[&[T]]) -> ~[T] { v.concat_vec() }
351-
352-
/// Concatenate a vector of vectors, placing a given separator between each
353-
pub fn connect_slices<T:Clone>(v: &[&[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
354-
355343
#[allow(missing_doc)]
356344
pub trait VectorVector<T> {
357345
// FIXME #5898: calling these .concat and .connect conflicts with
358346
// StrVector::con{cat,nect}, since they have generic contents.
347+
/// Flattens a vector of vectors of T into a single vector of T.
359348
fn concat_vec(&self) -> ~[T];
360-
fn connect_vec(&self, sep: &T) -> ~[T];
361-
}
362-
363-
impl<'self, T:Clone> VectorVector<T> for &'self [~[T]] {
364-
/// Flattens a vector of slices of T into a single vector of T.
365-
fn concat_vec(&self) -> ~[T] {
366-
self.flat_map(|inner| (*inner).clone())
367-
}
368349

369350
/// Concatenate a vector of vectors, placing a given separator between each.
370-
fn connect_vec(&self, sep: &T) -> ~[T] {
371-
let mut r = ~[];
372-
let mut first = true;
373-
for inner in self.iter() {
374-
if first { first = false; } else { r.push((*sep).clone()); }
375-
r.push_all((*inner).clone());
376-
}
377-
r
378-
}
351+
fn connect_vec(&self, sep: &T) -> ~[T];
379352
}
380353

381-
impl<'self,T:Clone> VectorVector<T> for &'self [&'self [T]] {
382-
/// Flattens a vector of slices of T into a single vector of T.
354+
impl<'self, T: Clone, V: Vector<T>> VectorVector<T> for &'self [V] {
383355
fn concat_vec(&self) -> ~[T] {
384-
self.flat_map(|&inner| inner.to_owned())
356+
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
357+
let mut result = with_capacity(size);
358+
for v in self.iter() {
359+
result.push_all(v.as_slice())
360+
}
361+
result
385362
}
386363

387-
/// Concatenate a vector of slices, placing a given separator between each.
388364
fn connect_vec(&self, sep: &T) -> ~[T] {
389-
let mut r = ~[];
365+
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
366+
let mut result = with_capacity(size + self.len());
390367
let mut first = true;
391-
for &inner in self.iter() {
392-
if first { first = false; } else { r.push((*sep).clone()); }
393-
r.push_all(inner);
368+
for v in self.iter() {
369+
if first { first = false } else { result.push(sep.clone()) }
370+
result.push_all(v.as_slice())
394371
}
395-
r
372+
result
396373
}
397374
}
398375

@@ -3109,24 +3086,21 @@ mod tests {
31093086

31103087
#[test]
31113088
fn test_concat() {
3112-
assert_eq!(concat([~[1], ~[2,3]]), ~[1, 2, 3]);
3089+
let v: [~[int], ..0] = [];
3090+
assert_eq!(v.concat_vec(), ~[]);
31133091
assert_eq!([~[1], ~[2,3]].concat_vec(), ~[1, 2, 3]);
31143092

3115-
assert_eq!(concat_slices([&[1], &[2,3]]), ~[1, 2, 3]);
31163093
assert_eq!([&[1], &[2,3]].concat_vec(), ~[1, 2, 3]);
31173094
}
31183095

31193096
#[test]
31203097
fn test_connect() {
3121-
assert_eq!(connect([], &0), ~[]);
3122-
assert_eq!(connect([~[1], ~[2, 3]], &0), ~[1, 0, 2, 3]);
3123-
assert_eq!(connect([~[1], ~[2], ~[3]], &0), ~[1, 0, 2, 0, 3]);
3098+
let v: [~[int], ..0] = [];
3099+
assert_eq!(v.connect_vec(&0), ~[]);
31243100
assert_eq!([~[1], ~[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
31253101
assert_eq!([~[1], ~[2], ~[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
31263102

3127-
assert_eq!(connect_slices([], &0), ~[]);
3128-
assert_eq!(connect_slices([&[1], &[2, 3]], &0), ~[1, 0, 2, 3]);
3129-
assert_eq!(connect_slices([&[1], &[2], &[3]], &0), ~[1, 0, 2, 0, 3]);
3103+
assert_eq!(v.connect_vec(&0), ~[]);
31303104
assert_eq!([&[1], &[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
31313105
assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
31323106
}
@@ -3758,7 +3732,9 @@ mod tests {
37583732
#[cfg(test)]
37593733
mod bench {
37603734
use extra::test::BenchHarness;
3735+
use iter::range;
37613736
use vec;
3737+
use vec::VectorVector;
37623738
use option::*;
37633739

37643740
#[bench]
@@ -3798,4 +3774,20 @@ mod bench {
37983774
xs + ys;
37993775
}
38003776
}
3777+
3778+
#[bench]
3779+
fn concat(bh: &mut BenchHarness) {
3780+
let xss: &[~[uint]] = vec::from_fn(100, |i| range(0, i).collect());
3781+
do bh.iter {
3782+
xss.concat_vec();
3783+
}
3784+
}
3785+
3786+
#[bench]
3787+
fn connect(bh: &mut BenchHarness) {
3788+
let xss: &[~[uint]] = vec::from_fn(100, |i| range(0, i).collect());
3789+
do bh.iter {
3790+
xss.connect_vec(&0);
3791+
}
3792+
}
38013793
}

0 commit comments

Comments
 (0)