Skip to content

Instantly share code, notes, and snippets.

@erickt
Last active December 31, 2015 22:08
Show Gist options
  • Save erickt/8051215 to your computer and use it in GitHub Desktop.
Save erickt/8051215 to your computer and use it in GitHub Desktop.
running 3 tests
test bench_collect ... bench: 11091 ns/iter (+/- 3046)
test bench_collect_with_iter ... bench: 11158 ns/iter (+/- 332)
test bench_collect_with_scan ... bench: 19737 ns/iter (+/- 13541)
test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured
extern mod extra;
use std::vec;
use std::result;
use extra::test::BenchHarness;
//////////////////////////////////////////////////////////////////////////////
trait MyScan<A>: Iterator<A> {
#[inline]
fn scan1<'r, St, B>(self, initial_state: St, f: 'r |&mut St, A| -> Option<B>)
-> Scan1<'r, A, B, Self, St> {
Scan1{iter: self, f: f, state: initial_state}
}
}
impl<A> MyScan<A> for vec::MoveIterator<A> {}
//////////////////////////////////////////////////////////////////////////////
pub struct Scan1<'a, A, B, T, St> {
priv iter: T,
priv f: 'a |&mut St, A| -> Option<B>,
/// The current internal state to be passed to the closure next.
state: St
}
impl<'a, A, B, T: Iterator<A>, St> Iterator<B> for Scan1<'a, A, B, T, St> {
#[inline]
fn next(&mut self) -> Option<B> {
self.iter.next().and_then(|a| (self.f)(&mut self.state, a))
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
// Note: this is different than `std::iter::Scan::size_hint`.
self.iter.size_hint()
}
}
//////////////////////////////////////////////////////////////////////////////
#[inline]
fn collect_with_scan<
T,
E,
Iter: Iterator<Result<T, E>>,
V: FromIterator<T>
>(iter: Iter) -> Result<V, E> {
let mut iter = iter.scan(None, |state, x| {
match x {
Ok(x) => Some(x),
Err(e) => {
*state = Some(e);
None
}
}
});
let v: V = FromIterator::from_iterator(&mut iter);
match iter.state {
Some(err) => Err(err),
None => Ok(v),
}
}
//////////////////////////////////////////////////////////////////////////////
#[inline]
fn collect_with_iter<
T,
E,
Iter: Iterator<Result<T, E>>,
V: FromIterator<T>
>(iter: Iter) -> Result<V, E> {
let mut iter = CollectIterator { iter: iter, state: None };
let v: V = FromIterator::from_iterator(&mut iter);
match iter.state {
Some(err) => Err(err),
None => Ok(v),
}
}
struct CollectIterator<Iter, E> {
iter: Iter,
state: Option<E>,
}
impl<T, E, Iter: Iterator<Result<T, E>>> Iterator<T> for CollectIterator<Iter, E> {
#[inline]
fn next(&mut self) -> Option<T> {
if self.state.is_some() {
None
} else {
match self.iter.next() {
Some(Ok(x)) => Some(x),
Some(Err(err)) => {
self.state = Some(err);
None
}
None => None,
}
}
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
self.iter.size_hint()
}
}
//////////////////////////////////////////////////////////////////////////////
#[bench]
fn bench_collect(bh: &mut BenchHarness) {
let expected = vec::from_elem(1000, 1);
bh.iter(|| {
let v: ~[Result<int, ~str>] = vec::from_elem(1000, Ok(1));
let result: Result<~[int], ~str> = result::collect(v.move_iter());
assert_eq!(result.unwrap(), expected);
});
}
#[bench]
fn bench_collect_with_scan(bh: &mut BenchHarness) {
let expected = vec::from_elem(1000, 1);
bh.iter(|| {
let v: ~[Result<int, ~str>] = vec::from_elem(1000, Ok(1));
let result: Result<~[int], ~str> = collect_with_scan(v.move_iter());
assert_eq!(result.unwrap(), expected);
});
}
#[bench]
fn bench_collect_with_iter(bh: &mut BenchHarness) {
let expected = vec::from_elem(1000, 1);
bh.iter(|| {
let v: ~[Result<int, ~str>] = vec::from_elem(1000, Ok(1));
let result: Result<~[int], ~str> = collect_with_iter(v.move_iter());
assert_eq!(result.unwrap(), expected);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment