diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2013-12-19 13:23:37 +1100 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2013-12-19 14:00:44 +1100 |
| commit | 81632513c13495fd269082d35916ebcd91d15658 (patch) | |
| tree | 3115d8965dcb8baca15748a7839c07868677da07 /src/libstd | |
| parent | b6933f8d8b86f78ac7b5f70f0781d794144763a0 (diff) | |
| download | rust-81632513c13495fd269082d35916ebcd91d15658.tar.gz rust-81632513c13495fd269082d35916ebcd91d15658.zip | |
std::vec: replace .insert with a small amount of unsafe code.
This makes the included benchmark more than 3 times faster. Also, `.unshift(x)` is now faster as `.insert(0, x)` which can reuse the allocation if necessary.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/vec.rs | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 65be214c14e..e58be99e564 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1661,20 +1661,28 @@ impl<T> OwnedVector<T> for ~[T] { } fn unshift(&mut self, x: T) { - let v = util::replace(self, ~[x]); - self.push_all_move(v); + self.insert(0, x) } - fn insert(&mut self, i: uint, x:T) { + + fn insert(&mut self, i: uint, x: T) { let len = self.len(); assert!(i <= len); - - self.push(x); - let mut j = len; - while j > i { - self.swap(j, j - 1); - j -= 1; + // space for the new element + self.reserve_additional(1); + + unsafe { // infallible + // The spot to put the new value + let p = self.as_mut_ptr().offset(i as int); + // Shift everything over to make space. (Duplicating the + // `i`th element into two consecutive places.) + ptr::copy_memory(p.offset(1), p, len - i); + // Write it in, overwriting the first copy of the `i`th + // element. + intrinsics::move_val_init(&mut *p, x); + self.set_len(len + 1); } } + fn remove(&mut self, i: uint) -> T { let len = self.len(); assert!(i < len); @@ -4144,6 +4152,7 @@ mod bench { use vec::VectorVector; use option::*; use ptr; + use rand::{weak_rng, Rng}; #[bench] fn iterator(bh: &mut BenchHarness) { @@ -4320,4 +4329,17 @@ mod bench { } }); } + + #[bench] + fn random_inserts(bh: &mut BenchHarness) { + let mut rng = weak_rng(); + bh.iter(|| { + let mut v = vec::from_elem(30, (0u, 0u)); + for _ in range(0, 100) { + let l = v.len(); + v.insert(rng.gen::<uint>() % (l + 1), + (1, 1)); + } + }) + } } |
