use criterion::{criterion_group, criterion_main, Criterion};
mod my_map_mod {
enum MyMapState { S, E }
struct MyMap<I: Iterator, R, F: FnMut(I::Item) -> R> {
state: MyMapState,
param_iter: I,
param_f: F,
}
impl<I: Iterator, R, F: FnMut(I::Item) -> R> Iterator for MyMap<I, R, F> {
type Item = R;
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn next(&mut self) -> Option<R> {
loop {
match self.state {
MyMapState::S => {
match self.param_iter.next() {
Some(x) => { return Some((self.param_f)(x)); }
None => { self.state = MyMapState::E; }
}
},
MyMapState::E => {
return None
}
}
}
}
}
pub fn my_map<I: Iterator, R, F: FnMut(I::Item) -> R>(iter: I, f: F) -> impl Iterator<Item = R> {
MyMap { state: MyMapState::S, param_iter: iter, param_f: f }
}
}
use my_map_mod::my_map;
#[giver]
fn my_map<I, F, R>(iter: I, f: F) -> R
where
I: Iterator,
F: FnMut(I::Item) -> R,
R: Iterator<Item=I::Item>,
{
for x in iter {
give!(f(x))
}
}
mod simp_map_mod {
pub struct SimpMap<I: Iterator, R, F: FnMut(I::Item) -> R> {
iter: I,
f: F,
}
impl<I: Iterator, R, F: FnMut(I::Item) -> R> Iterator for SimpMap<I, R, F> {
type Item = R;
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn next(&mut self) -> Option<R> {
self.iter.next().map(&mut self.f)
}
}
pub fn simp_map<I: Iterator, R, F: FnMut(I::Item) -> R>(iter: I, f: F) -> SimpMap<I, R, F> {
SimpMap { iter, f }
}
}
use simp_map_mod::simp_map;
fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("std map", |b| b.iter(||
(1..1024).map(|x| x + 1).map(|x| (((x + 12) * 24) ^ 42)/x).collect::<Vec<_>>()
));
c.bench_function("my map", |b| b.iter(||
my_map(my_map(1..1024, |x| x + 1), |x| (((x + 12) * 24) ^ 42)/x).collect::<Vec<_>>()
));
c.bench_function("simp map", |b| b.iter(||
simp_map(simp_map(1..1024, |x| x + 1), |x| (((x + 12) * 24) ^ 42)/x).collect::<Vec<_>>()
));
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);