|
#[macro_use] |
|
extern crate criterion; |
|
|
|
use crate::criterion::Criterion; |
|
use std::time::Duration; |
|
|
|
use itertools::izip; |
|
use rand::Rng; |
|
|
|
type Result<T> = std::result::Result<T, String>; |
|
|
|
// #[no_mangle] |
|
// #[inline(always)] |
|
// #[inline(never)] |
|
fn simple_sum(a: i32, b: i32, c: i32, d: i32) -> Result<i32> { |
|
Ok(a + b + c + d) |
|
} |
|
|
|
// #[no_mangle] |
|
// #[inline(always)] |
|
// #[inline(never)] |
|
fn curried_sum(a: i32, b: i32, c: i32, d: i32) -> Result<i32> { |
|
Ok(fn_fn_fn_fn(a)?(b)?(c)?(d)?) |
|
} |
|
|
|
fn fn_fn_fn_fn( |
|
a: i32, |
|
) -> Result<Box<dyn Fn(i32) -> Result<Box<dyn Fn(i32) -> Result<Box<dyn Fn(i32) -> Result<i32>>>>>>> |
|
{ |
|
Ok(Box::new(move |b| { |
|
Ok(Box::new(move |c| Ok(Box::new(move |d| Ok(a + b + c + d))))) |
|
})) |
|
} |
|
|
|
// #[no_mangle] |
|
// #[inline(always)] |
|
// #[inline(never)] |
|
fn continuation_sum(a: i32, b: i32, c: i32, d: i32) -> Result<i32> { |
|
fn_continuation(a, &|after_a| /*_*/ { |
|
after_a?(b, &|after_b| /*_*/ { |
|
after_b?(c, &|after_c| /*_*/ { |
|
after_c?(d) |
|
}) |
|
}) |
|
}) |
|
} |
|
|
|
fn fn_continuation( |
|
a: i32, |
|
after_a: &dyn Fn( |
|
Result< |
|
&dyn Fn( |
|
/*b*/ i32, |
|
/* after_b */ |
|
&dyn Fn( |
|
Result< |
|
&dyn Fn( |
|
/*c*/ i32, |
|
/* after_c */ |
|
&dyn Fn( |
|
// calculate final result |
|
Result<&dyn Fn(/*d*/ i32) -> Result<i32>>, |
|
) -> Result<i32>, |
|
) -> Result<i32>, |
|
>, |
|
) -> Result<i32>, |
|
) -> Result<i32>, |
|
>, |
|
) -> Result<i32>, |
|
) -> Result<i32> { |
|
after_a(Ok(&move |b, after_b| /*-> Result<i32> */ { |
|
after_b(Ok(&move |c, after_c| /*-> Result<i32> */ { |
|
after_c(Ok(&move |d| /*-> Result<i32> */ { |
|
Ok(a + b + c + d) |
|
})) |
|
})) |
|
})) |
|
} |
|
|
|
fn criterion_benchmark(c: &mut Criterion) { |
|
let a_vals = generate_array(); |
|
let b_vals = generate_array(); |
|
let c_vals = generate_array(); |
|
let d_vals = generate_array(); |
|
|
|
let mut group = c.benchmark_group("function-calls"); |
|
group.measurement_time(Duration::from_secs(10)); |
|
// quick |
|
// group.warm_up_time(Duration::from_secs(1)); |
|
// group.measurement_time(Duration::from_secs(2)); |
|
|
|
group.bench_function("simple_sum", |b| { |
|
b.iter(|| { |
|
let sum = izip!(&a_vals, &b_vals, &c_vals, &d_vals) |
|
.map(|(a, b, c, d)| simple_sum(*a, *b, *c, *d).unwrap()) |
|
.sum::<i32>(); |
|
criterion::black_box(sum); |
|
}) |
|
}); |
|
|
|
group.bench_function("curried_sum", |b| { |
|
b.iter(|| { |
|
let sum = izip!(&a_vals, &b_vals, &c_vals, &d_vals) |
|
.map(|(a, b, c, d)| curried_sum(*a, *b, *c, *d).unwrap()) |
|
.sum::<i32>(); |
|
criterion::black_box(sum); |
|
}) |
|
}); |
|
|
|
group.bench_function("continuation_sum", |b| { |
|
b.iter(|| { |
|
let sum = izip!(&a_vals, &b_vals, &c_vals, &d_vals) |
|
.map(|(a, b, c, d)| continuation_sum(*a, *b, *c, *d).unwrap()) |
|
.sum::<i32>(); |
|
criterion::black_box(sum); |
|
}) |
|
}); |
|
} |
|
|
|
fn generate_array() -> Vec<i32> { |
|
let mut rng = rand::rng(); |
|
(0..10_000).map(|_| rng.random_range(0..100)).collect() |
|
} |
|
|
|
criterion_group!(benches, criterion_benchmark); |
|
criterion_main!(benches); |