use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rust_finprim::derivatives::{npv_prime_r, pv_prime_r};
use rust_finprim::tvm::npv;
use rust_finprim::FloatLike;
pub fn npv_old<T: FloatLike>(rate: T, cash_flows: &[T]) -> T {
cash_flows
.iter()
.enumerate()
.map(|(t, &cf)| cf / (T::one() + rate).powf(T::from_usize(t)))
.sum()
}
pub fn npv_prime_r_niave<T: FloatLike>(rate: T, cash_flows: &[T]) -> T {
cash_flows
.iter()
.enumerate()
.map(|(t, &cf)| pv_prime_r(rate, T::from_usize(t), cf))
.sum()
}
fn criterion_benchmark(c: &mut Criterion) {
let rate = 0.1;
let cash_flow: Vec<f64> = vec![
-100.0, 50.0, 40.0, 30.0, 20.0, 10.0, 5.0, 2.0, 1.0, 0.5, 0.1, 0.05, 0.01, 0.005, 0.001, 0.0005, 0.0001,
0.00005, 0.00001, 0.000005, 0.000001, 10000.0, 5000.0, 2000.0, 1000.0, 500.0, 200.0, 100.0, 50.0, 1000000.0,
500000.0, 200000.0, 100000.0, 50000.0, 20000.0, 10000.0, 500000.0, 20000.0, 10000.0, 5000.0, 2000.0, 1000.0,
500.0, 20.0, 10.0, 5.0, 2.0, 1.0, 0.5, 0.1, 0.05, 0.01, 0.005, 0.001, 50000.0, 25000.0, 10000.0, 5000.0,
2000.0, 1000.0, 500.0, 200.0, 100.0, 50.0, 20.0, 10.0, 5.0, 2.0, 1.0, 0.5, 0.1, 0.05, -100.0, 50.0, 40.0, 30.0,
20.0, 10.0, 5.0, 2.0, 1.0, 0.5, 0.1, 0.05, 0.01, 0.005, 0.001, 0.0005, 0.0001, 0.00005, 0.00001, 0.000005,
0.000001, 10000.0, 5000.0, 2000.0, 1000.0, 500.0, 200.0, 100.0, 50.0, 1000000.0, 500000.0, 200000.0, 100000.0,
50000.0, 20000.0, 10000.0, 500000.0, 20000.0, 10000.0, 5000.0, 2000.0, 1000.0, 500.0, 20.0, 10.0, 5.0, 2.0,
1.0, 0.5, 0.1, 0.05, 0.01, 0.005, 0.001, 50000.0, 25000.0, 10000.0, 5000.0, 2000.0, 1000.0, 500.0, 200.0,
100.0, 50.0, 20.0, 10.0, 5.0, 2.0, 1.0, 0.5, 0.1, 0.05, -100.0, 50.0, 40.0, 30.0, 20.0, 10.0, 5.0, 2.0, 1.0,
0.5, 0.1, 0.05, 0.01, 0.005, 0.001, 0.0005, 0.0001, 0.00005, 0.00001, 0.000005, 0.000001, 10000.0, 5000.0,
2000.0, 1000.0, 500.0, 200.0, 100.0, 50.0, 1000000.0, 500000.0, 200000.0, 100000.0, 50000.0, 20000.0, 10000.0,
500000.0, 20000.0, 10000.0, 5000.0, 2000.0, 1000.0, 500.0, 20.0, 10.0, 5.0, 2.0, 1.0, 0.5, 0.1, 0.05, 0.01,
0.005, 0.001, 50000.0, 25000.0, 10000.0, 5000.0, 2000.0, 1000.0, 500.0, 200.0, 100.0, 50.0, 20.0, 10.0, 5.0,
2.0, 1.0, 0.5, 0.1, 0.05, -100.0, 50.0, 40.0, 30.0, 20.0, 10.0, 5.0, 2.0, 1.0, 0.5, 0.1, 0.05, 0.01, 0.005,
0.001, 0.0005, 0.0001, 0.00005, 0.00001, 0.000005, 0.000001, 10000.0, 5000.0, 2000.0, 1000.0, 500.0, 200.0,
100.0, 50.0, 1000000.0, 500000.0, 200000.0, 100000.0, 50000.0, 20000.0, 10000.0, 500000.0, 20000.0, 10000.0,
5000.0, 2000.0, 1000.0, 500.0, 20.0, 10.0, 5.0, 2.0, 1.0, 0.5, 0.1, 0.05, 0.01, 0.005, 0.001, 50000.0, 25000.0,
10000.0, 5000.0, 2000.0, 1000.0, 500.0, 200.0, 100.0, 50.0, 20.0, 10.0, 5.0, 2.0, 1.0, 0.5, 0.1, 0.05,
];
c.bench_function("npv_old", |b| {
b.iter(|| npv_old(black_box(rate), black_box(&cash_flow)))
});
c.bench_function("npv", |b| b.iter(|| npv(black_box(rate), black_box(&cash_flow))));
c.bench_function("npv_prime_r_niave", |b| {
b.iter(|| npv_prime_r_niave(black_box(rate), black_box(&cash_flow)))
});
c.bench_function("npv_prime_r", |b| {
b.iter(|| npv_prime_r(black_box(rate), black_box(&cash_flow)))
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);