about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <eric.holk@gmail.com>2012-06-27 11:32:22 -0700
committerEric Holk <eric.holk@gmail.com>2012-06-27 11:32:22 -0700
commit133fdc11484794274b0c9b7dca9f05196d3ed01d (patch)
treeaf16f2d23c7a2580178e35c24943db77a463ab3a
parent404afcbb41898cf7f516f07cae3dc42e47bda46d (diff)
downloadrust-133fdc11484794274b0c9b7dca9f05196d3ed01d.tar.gz
rust-133fdc11484794274b0c9b7dca9f05196d3ed01d.zip
Remove unnecessary bounds checks in vec::push_all (issue #2719)
Don't needlessly drop closures (issue #2603)
-rw-r--r--src/libcore/vec.rs26
-rw-r--r--src/rustc/middle/ty.rs6
-rw-r--r--src/test/bench/core-std.rs33
3 files changed, 51 insertions, 14 deletions
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index be402f317a1..8f1ff7d1a01 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -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;
 }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index 798dc6aee9b..26495e233ff 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -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 }
     };
 
diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs
index 9ea0ad51feb..9e1f88690d1 100644
--- a/src/test/bench/core-std.rs
+++ b/src/test/bench/core-std.rs
@@ -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);
+        }
+    }
+}