use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use cord_sparse::*; use std::time::Duration; fn product_fn(fp: &FixedPoint) -> impl Fn(&[i64]) -> i64 + '_ { move |pt: &[i64]| { let mut result = fp.one(); for &x in pt { result = fp.mul(result, x); } result } } fn bench_solve(c: &mut Criterion) { let fp = FixedPoint::new(32); let basis = MonomialBasis; let pts = GoldenPoints; let configs: Vec<(usize, usize)> = vec![ (2, 25), (2, 75), (2, 216), (4, 10), (4, 25), (4, 56), (8, 5), (8, 8), (8, 14), (16, 4), (16, 7), (32, 3), (32, 5), ]; let mut group = c.benchmark_group("solve"); group.warm_up_time(Duration::from_millis(500)); group.measurement_time(Duration::from_secs(3)); for &(d, bound) in &configs { let n = cord_sparse::index::binom(bound + d, d); if n > 500_000 { group.sample_size(10); } else { group.sample_size(30); } let iter = BoundedSumIter::new(d, bound); let f = product_fn(&fp); let rhs = evaluate_function(&iter, &f, &pts, &fp); let mut op = create_interpolation_operator(fp, &iter, &basis, &pts); op.solve(rhs.clone()); group.bench_with_input( BenchmarkId::new(format!("d{d}"), format!("b{bound}_n{n}")), &(d, bound), |b, &(d, bound)| { let iter = BoundedSumIter::new(d, bound); let f = product_fn(&fp); let rhs = evaluate_function(&iter, &f, &pts, &fp); let mut op = create_interpolation_operator(fp, &iter, &basis, &pts); b.iter(|| { op.solve(rhs.clone()) }); }, ); } group.finish(); } fn bench_apply(c: &mut Criterion) { let fp = FixedPoint::new(32); let basis = MonomialBasis; let pts = GoldenPoints; let configs: Vec<(usize, usize)> = vec![ (2, 75), (4, 25), (8, 8), (16, 5), ]; let mut group = c.benchmark_group("apply"); group.warm_up_time(Duration::from_millis(500)); group.measurement_time(Duration::from_secs(3)); for &(d, bound) in &configs { let n = cord_sparse::index::binom(bound + d, d); if n > 100_000 { group.sample_size(10); } else { group.sample_size(30); } let iter = BoundedSumIter::new(d, bound); let f = product_fn(&fp); let rhs = evaluate_function(&iter, &f, &pts, &fp); let mut op = create_interpolation_operator(fp, &iter, &basis, &pts); let coeffs = op.solve(rhs); group.bench_with_input( BenchmarkId::new(format!("d{d}"), format!("b{bound}_n{n}")), &coeffs, |b, coeffs| { b.iter(|| { op.apply(coeffs.clone()) }); }, ); } group.finish(); } criterion_group!(benches, bench_solve, bench_apply); criterion_main!(benches);