]> git.lizzy.rs Git - rust.git/commitdiff
std: use ptr.offset where possible in the vec iterator.
authorHuon Wilson <dbau.pp+github@gmail.com>
Fri, 2 Aug 2013 13:34:11 +0000 (23:34 +1000)
committerDaniel Micay <danielmicay@gmail.com>
Sat, 3 Aug 2013 07:13:11 +0000 (03:13 -0400)
Closes #8212.

src/libstd/vec.rs

index ad5ded2002a2d95c0d8e608e701228cceaa61a74..5f66d93b6d9430452afe8ae8b972416376b0c769 100644 (file)
@@ -2141,11 +2141,15 @@ fn next(&mut self) -> Option<$elem> {
                         None
                     } else {
                         let old = self.ptr;
-                        // purposefully don't use 'ptr.offset' because for
-                        // vectors with 0-size elements this would return the
-                        // same pointer.
-                        self.ptr = cast::transmute(self.ptr as uint +
-                                                   sys::nonzero_size_of::<T>());
+                        self.ptr = if sys::size_of::<T>() == 0 {
+                            // purposefully don't use 'ptr.offset' because for
+                            // vectors with 0-size elements this would return the
+                            // same pointer.
+                            cast::transmute(self.ptr as uint + 1)
+                        } else {
+                            self.ptr.offset(1)
+                        };
+
                         Some(cast::transmute(old))
                     }
                 }
@@ -2171,9 +2175,12 @@ fn next_back(&mut self) -> Option<$elem> {
                     if self.end == self.ptr {
                         None
                     } else {
-                        // See above for why 'ptr.offset' isn't used
-                        self.end = cast::transmute(self.end as uint -
-                                                   sys::nonzero_size_of::<T>());
+                        self.end = if sys::size_of::<T>() == 0 {
+                            // See above for why 'ptr.offset' isn't used
+                            cast::transmute(self.end as uint - 1)
+                        } else {
+                            self.end.offset(-1)
+                        };
                         Some(cast::transmute(self.end))
                     }
                 }
@@ -3566,3 +3573,26 @@ fn test_iter_zero_sized() {
         assert!(cnt == 3);
     }
 }
+
+#[cfg(test)]
+mod bench {
+    use extra::test::BenchHarness;
+    use vec;
+    use option::*;
+
+    #[bench]
+    fn iterator(bh: &mut BenchHarness) {
+        // peculiar numbers to stop LLVM from optimising the summation
+        // out.
+        let v = vec::from_fn(100, |i| i ^ (i << 1) ^ (i >> 1));
+
+        do bh.iter {
+            let mut sum = 0;
+            foreach x in v.iter() {
+                sum += *x;
+            }
+            // sum == 11806, to stop dead code elimination.
+            if sum == 0 {fail!()}
+        }
+    }
+}