Remove unnecessary bounds checks in vec::push_all (issue #2719)

Don't needlessly drop closures (issue #2603)
This commit is contained in:
Eric Holk 2012-06-27 11:32:22 -07:00
parent 404afcbb41
commit 133fdc1148
3 changed files with 51 additions and 14 deletions

View File

@ -451,12 +451,20 @@ fn push_slow<T>(&v: [const T]/~, +initval: T) {
}
}
// Unchecked vector indexing
#[inline(always)]
unsafe fn ref<T: copy>(v: [const T]/&, i: uint) -> T {
unpack_slice(v) {|p, _len|
*ptr::offset(p, i)
}
}
#[inline(always)]
fn push_all<T: copy>(&v: [const T]/~, rhs: [const T]/&) {
reserve(v, v.len() + rhs.len());
for uint::range(0u, rhs.len()) {|i|
push(v, rhs[i]);
push(v, unsafe { ref(rhs, i) })
}
}
@ -464,19 +472,9 @@ fn push_all<T: copy>(&v: [const T]/~, rhs: [const T]/&) {
#[inline(always)]
pure fn append<T: copy>(lhs: [T]/&, rhs: [const T]/&) -> [T]/~ {
let mut v = []/~;
let mut i = 0u;
while i < lhs.len() {
unsafe { // This is impure, but it appears pure to the caller.
push(v, lhs[i]);
}
i += 1u;
}
i = 0u;
while i < rhs.len() {
unsafe { // This is impure, but it appears pure to the caller.
push(v, rhs[i]);
}
i += 1u;
unchecked {
push_all(v, lhs);
push_all(v, rhs);
}
ret v;
}

View File

@ -1234,6 +1234,12 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
}
accum
}
ty_fn(fty) {
alt fty.proto {
proto_bare | proto_any | proto_block { false }
_ { true }
}
}
_ { true }
};

View File

@ -22,6 +22,8 @@ fn main(argv: [str]/~) {
#bench[shift_push];
#bench[read_line];
#bench[str_set];
#bench[vec_append];
#bench[vec_push_all];
}
fn run_test(name: str, test: fn()) {
@ -72,3 +74,34 @@ fn str_set() {
}
}
}
fn vec_append() {
let r = rand::rng();
let mut v = []/~;
for uint::range(0, 1500) {|i|
let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
if r.gen_bool() {
v += rv;
}
else {
v = rv + v;
}
}
}
fn vec_push_all() {
let r = rand::rng();
let mut v = []/~;
for uint::range(0, 1500) {|i|
let mut rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
if r.gen_bool() {
vec::push_all(v, rv);
}
else {
v <-> rv;
vec::push_all(v, rv);
}
}
}