diff options
Diffstat (limited to 'benches/benchmarks/custom_measurement.rs')
-rwxr-xr-x | benches/benchmarks/custom_measurement.rs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/benches/benchmarks/custom_measurement.rs b/benches/benchmarks/custom_measurement.rs new file mode 100755 index 0000000..c685f38 --- /dev/null +++ b/benches/benchmarks/custom_measurement.rs @@ -0,0 +1,118 @@ +use criterion::{ + black_box, criterion_group, + measurement::{Measurement, ValueFormatter}, + Criterion, Throughput, +}; +use std::time::{Duration, Instant}; + +struct HalfSecFormatter; +impl ValueFormatter for HalfSecFormatter { + fn format_value(&self, value: f64) -> String { + // The value will be in nanoseconds so we have to convert to half-seconds. + format!("{} s/2", value * 2f64 * 10f64.powi(-9)) + } + + fn format_throughput(&self, throughput: &Throughput, value: f64) -> String { + match *throughput { + Throughput::Bytes(bytes) => { + format!("{} b/s/2", (bytes as f64) / (value * 2f64 * 10f64.powi(-9))) + } + Throughput::Elements(elems) => format!( + "{} elem/s/2", + (elems as f64) / (value * 2f64 * 10f64.powi(-9)) + ), + } + } + + fn scale_values(&self, _typical: f64, values: &mut [f64]) -> &'static str { + for val in values { + *val *= 2f64 * 10f64.powi(-9); + } + + "s/2" + } + + fn scale_throughputs( + &self, + _typical: f64, + throughput: &Throughput, + values: &mut [f64], + ) -> &'static str { + match *throughput { + Throughput::Bytes(bytes) => { + for val in values { + *val = (bytes as f64) / (*val * 2f64 * 10f64.powi(-9)) + } + + "b/s/2" + } + Throughput::Elements(elems) => { + for val in values { + *val = (elems as f64) / (*val * 2f64 * 10f64.powi(-9)) + } + + "elem/s/2" + } + } + } + + fn scale_for_machines(&self, values: &mut [f64]) -> &'static str { + for val in values { + *val *= 2f64 * 10f64.powi(-9); + } + + "s/2" + } +} + +const NANOS_PER_SEC: u64 = 1_000_000_000; + +/// Silly "measurement" that is really just wall-clock time reported in half-seconds. +struct HalfSeconds; +impl Measurement for HalfSeconds { + type Intermediate = Instant; + type Value = Duration; + + fn start(&self) -> Self::Intermediate { + Instant::now() + } + fn end(&self, i: Self::Intermediate) -> Self::Value { + i.elapsed() + } + fn add(&self, v1: &Self::Value, v2: &Self::Value) -> Self::Value { + *v1 + *v2 + } + fn zero(&self) -> Self::Value { + Duration::from_secs(0) + } + fn to_f64(&self, val: &Self::Value) -> f64 { + let nanos = val.as_secs() * NANOS_PER_SEC + u64::from(val.subsec_nanos()); + nanos as f64 + } + fn formatter(&self) -> &dyn ValueFormatter { + &HalfSecFormatter + } +} + +fn fibonacci_slow(n: u64) -> u64 { + match n { + 0 | 1 => 1, + n => fibonacci_slow(n - 1) + fibonacci_slow(n - 2), + } +} + +fn fibonacci_cycles(criterion: &mut Criterion<HalfSeconds>) { + criterion.bench_function("fibonacci_custom_measurement", |bencher| { + bencher.iter(|| fibonacci_slow(black_box(10))) + }); +} + +fn alternate_measurement() -> Criterion<HalfSeconds> { + Criterion::default().with_measurement(HalfSeconds) +} + +criterion_group! { + name = benches; + config = alternate_measurement(); + targets = fibonacci_cycles +} |