about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Pinot <texitoi@texitoi.eu>2014-10-14 09:41:57 +0200
committerGuillaume Pinot <texitoi@texitoi.eu>2014-10-14 09:41:57 +0200
commitb8786a5cbac0c0868e28000f8936ae91fd2ef926 (patch)
tree26e6839e7c944959c453452b018c93935d7a8837
parent4d031d7f86a66270d3cfc28a2ecf75706a67054b (diff)
downloadrust-b8786a5cbac0c0868e28000f8936ae91fd2ef926.tar.gz
rust-b8786a5cbac0c0868e28000f8936ae91fd2ef926.zip
improve shootout-reverse-complement.rs using unsafe code
-rw-r--r--src/test/bench/shootout-reverse-complement.rs47
1 files changed, 36 insertions, 11 deletions
diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs
index e3fa6334f77..e42723059cf 100644
--- a/src/test/bench/shootout-reverse-complement.rs
+++ b/src/test/bench/shootout-reverse-complement.rs
@@ -98,19 +98,44 @@ fn main() {
         // reverse complement, as
         //    seq.reverse(); for c in seq.iter_mut() {*c = complements[*c]}
         // but faster:
-        let mut it = seq.iter_mut();
-        loop {
-            match (it.next(), it.next_back()) {
-                (Some(front), Some(back)) => {
-                    let tmp = complements[*front as uint];
-                    *front = complements[*back as uint];
-                    *back = tmp;
-                }
-                (Some(last), None) => *last = complements[*last as uint], // last element
-                _ => break // vector exhausted.
-            }
+        for (front, back) in TwoSideIterator::new(seq) {
+            let tmp = complements[*front as uint];
+            *front = complements[*back as uint];
+            *back = tmp;
+        }
+        if seq.len() % 2 == 1 {
+            let middle = &mut seq[seq.len() / 2];
+            *middle = complements[*middle as uint];
         }
     }
 
     stdout().write(data.as_slice()).unwrap();
 }
+
+pub struct TwoSideIterator<'a, T: 'a> {
+    last: uint,
+    nb: uint,
+    cur: uint,
+    slice: &'a mut [T]
+}
+impl<'a, T> TwoSideIterator<'a, T> {
+    pub fn new(s: &'a mut [T]) -> TwoSideIterator<'a, T> {
+        TwoSideIterator {
+            last: s.len() - 1,
+            nb: s.len() / 2,
+            cur: 0,
+            slice: s
+        }
+    }
+}
+impl<'a, T> Iterator<(&'a mut T, &'a mut T)> for TwoSideIterator<'a, T> {
+    fn next(&mut self) -> Option<(&'a mut T, &'a mut T)> {
+        if self.cur >= self.nb { return None; }
+        let res = unsafe {
+            (std::mem::transmute(self.slice.unsafe_mut(self.cur)),
+             std::mem::transmute(self.slice.unsafe_mut(self.last - self.cur)))
+        };
+        self.cur += 1;
+        Some(res)
+    }
+}