Skip to content

Commit b8786a5

Browse files
committed
improve shootout-reverse-complement.rs using unsafe code
1 parent 4d031d7 commit b8786a5

File tree

1 file changed

+36
-11
lines changed

1 file changed

+36
-11
lines changed

src/test/bench/shootout-reverse-complement.rs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,44 @@ fn main() {
9898
// reverse complement, as
9999
// seq.reverse(); for c in seq.iter_mut() {*c = complements[*c]}
100100
// but faster:
101-
let mut it = seq.iter_mut();
102-
loop {
103-
match (it.next(), it.next_back()) {
104-
(Some(front), Some(back)) => {
105-
let tmp = complements[*front as uint];
106-
*front = complements[*back as uint];
107-
*back = tmp;
108-
}
109-
(Some(last), None) => *last = complements[*last as uint], // last element
110-
_ => break // vector exhausted.
111-
}
101+
for (front, back) in TwoSideIterator::new(seq) {
102+
let tmp = complements[*front as uint];
103+
*front = complements[*back as uint];
104+
*back = tmp;
105+
}
106+
if seq.len() % 2 == 1 {
107+
let middle = &mut seq[seq.len() / 2];
108+
*middle = complements[*middle as uint];
112109
}
113110
}
114111

115112
stdout().write(data.as_slice()).unwrap();
116113
}
114+
115+
pub struct TwoSideIterator<'a, T: 'a> {
116+
last: uint,
117+
nb: uint,
118+
cur: uint,
119+
slice: &'a mut [T]
120+
}
121+
impl<'a, T> TwoSideIterator<'a, T> {
122+
pub fn new(s: &'a mut [T]) -> TwoSideIterator<'a, T> {
123+
TwoSideIterator {
124+
last: s.len() - 1,
125+
nb: s.len() / 2,
126+
cur: 0,
127+
slice: s
128+
}
129+
}
130+
}
131+
impl<'a, T> Iterator<(&'a mut T, &'a mut T)> for TwoSideIterator<'a, T> {
132+
fn next(&mut self) -> Option<(&'a mut T, &'a mut T)> {
133+
if self.cur >= self.nb { return None; }
134+
let res = unsafe {
135+
(std::mem::transmute(self.slice.unsafe_mut(self.cur)),
136+
std::mem::transmute(self.slice.unsafe_mut(self.last - self.cur)))
137+
};
138+
self.cur += 1;
139+
Some(res)
140+
}
141+
}

0 commit comments

Comments
 (0)