From 59cec8d338b76b5bc4329c6e4f26a4c571b06846 Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Wed, 31 Jan 2024 22:39:00 -0600 Subject: [PATCH] Add benchmark for rounding methods of `FixedDecimal` --- utils/fixed_decimal/Cargo.toml | 2 +- utils/fixed_decimal/benches/fixed_decimal.rs | 49 ++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/utils/fixed_decimal/Cargo.toml b/utils/fixed_decimal/Cargo.toml index 958643f487d..b5ebc56ff01 100644 --- a/utils/fixed_decimal/Cargo.toml +++ b/utils/fixed_decimal/Cargo.toml @@ -40,7 +40,7 @@ criterion = "0.4" [features] std = [] -bench = [] +bench = ["ryu"] experimental = [] ryu = ["dep:ryu"] diff --git a/utils/fixed_decimal/benches/fixed_decimal.rs b/utils/fixed_decimal/benches/fixed_decimal.rs index 7042e0669ab..33a8cfcdd77 100644 --- a/utils/fixed_decimal/benches/fixed_decimal.rs +++ b/utils/fixed_decimal/benches/fixed_decimal.rs @@ -22,6 +22,15 @@ fn triangular_nums(range: f64) -> Vec { .collect() } +#[cfg(feature = "bench")] +fn triangular_floats(range: f64) -> impl Iterator { + // Use Lcg64Xsh32, a small, fast PRNG.s + // Generate 1000 numbers between -range and +range, weighted around 0. + let rng = Lcg64Xsh32::seed_from_u64(2024); + let dist = Triangular::new(-range, range, 0.0).unwrap(); + dist.sample_iter(rng).take(1000) +} + fn overview_bench(c: &mut Criterion) { let nums = triangular_nums(1e4); let values: Vec<_> = nums.iter().map(|n| n.to_string()).collect(); @@ -51,6 +60,7 @@ fn overview_bench(c: &mut Criterion) { larger_isize_benches(c); to_string_benches(c); from_string_benches(c); + rounding_benches(c); } } @@ -158,5 +168,44 @@ fn from_string_benches(c: &mut Criterion) { } } +#[cfg(feature = "bench")] +fn rounding_benches(c: &mut Criterion) { + use fixed_decimal::FloatPrecision; + #[allow(clippy::type_complexity)] // most compact representation in code + const ROUNDING_FNS: [(&str, fn(FixedDecimal, i16) -> FixedDecimal); 9] = [ + ("ceil", FixedDecimal::ceiled), + ("floor", FixedDecimal::floored), + ("expand", FixedDecimal::expanded), + ("trunc", FixedDecimal::trunced), + ("half_ceil", FixedDecimal::half_ceiled), + ("half_floor", FixedDecimal::half_floored), + ("half_expand", FixedDecimal::half_expanded), + ("half_trunc", FixedDecimal::half_trunced), + ("half_even", FixedDecimal::half_evened), + ]; + + let nums: Vec<_> = triangular_floats(1e7) + .map(|f| FixedDecimal::try_from_f64(f, FloatPrecision::Floating).unwrap()) + .collect(); + let mut group = c.benchmark_group("rounding"); + + for (name, rounding_fn) in ROUNDING_FNS { + group.bench_function(name, |b| { + b.iter(|| { + for offset in -5..=5 { + nums.iter() + .cloned() + .map(|num| rounding_fn(black_box(num), offset)) + .for_each(|num| { + black_box(num); + }); + } + }) + }); + } + + group.finish() +} + criterion_group!(benches, overview_bench,); criterion_main!(benches);