From 1a6f1ebad541e179f7418ce0102540cb15fb455e Mon Sep 17 00:00:00 2001 From: Guillaume Pinot Date: Thu, 16 Oct 2014 00:11:06 +0200 Subject: [PATCH] shootout-reverse-complement: reimplement TwoSideIter using pointers --- src/test/bench/shootout-reverse-complement.rs | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index e42723059cfac..352d351973bc6 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -96,9 +96,9 @@ fn main() { } // reverse complement, as - // seq.reverse(); for c in seq.iter_mut() {*c = complements[*c]} + // seq.reverse(); for c in seq.iter_mut() { *c = complements[*c] } // but faster: - for (front, back) in TwoSideIterator::new(seq) { + for (front, back) in two_side_iter(seq) { let tmp = complements[*front as uint]; *front = complements[*back as uint]; *back = tmp; @@ -112,30 +112,39 @@ fn main() { stdout().write(data.as_slice()).unwrap(); } -pub struct TwoSideIterator<'a, T: 'a> { - last: uint, - nb: uint, - cur: uint, - slice: &'a mut [T] +pub struct TwoSideIter<'a, T: 'a> { + first: *mut T, + last: *mut T, + marker: std::kinds::marker::ContravariantLifetime<'a>, + marker2: std::kinds::marker::NoCopy } -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 - } + +pub fn two_side_iter<'a, T>(slice: &'a mut [T]) -> TwoSideIter<'a, T> { + let len = slice.len(); + let first = slice.as_mut_ptr(); + let last = if len == 0 { + first + } else { + unsafe { first.offset(len as int - 1) } + }; + + TwoSideIter { + first: first, + last: last, + marker: std::kinds::marker::ContravariantLifetime, + marker2: std::kinds::marker::NoCopy } } -impl<'a, T> Iterator<(&'a mut T, &'a mut T)> for TwoSideIterator<'a, T> { + +impl<'a, T> Iterator<(&'a mut T, &'a mut T)> for TwoSideIter<'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) + if self.first < self.last { + let result = unsafe { (&mut *self.first, &mut *self.last) }; + self.first = unsafe { self.first.offset(1) }; + self.last = unsafe { self.last.offset(-1) }; + Some(result) + } else { + None + } } }