fparkan/vendor/ryu/examples/upstream_benchmark.rs

86 lines
2.1 KiB
Rust
Raw Normal View History

// cargo run --example upstream_benchmark --release
use rand::{Rng, SeedableRng};
const SAMPLES: usize = 10000;
const ITERATIONS: usize = 1000;
struct MeanAndVariance {
n: i64,
mean: f64,
m2: f64,
}
impl MeanAndVariance {
fn new() -> Self {
MeanAndVariance {
n: 0,
mean: 0.0,
m2: 0.0,
}
}
fn update(&mut self, x: f64) {
self.n += 1;
let d = x - self.mean;
self.mean += d / self.n as f64;
let d2 = x - self.mean;
self.m2 += d * d2;
}
fn variance(&self) -> f64 {
self.m2 / (self.n - 1) as f64
}
fn stddev(&self) -> f64 {
self.variance().sqrt()
}
}
macro_rules! benchmark {
($name:ident, $ty:ident) => {
fn $name() -> usize {
let mut rng = rand_xorshift::XorShiftRng::from_seed([123u8; 16]);
let mut mv = MeanAndVariance::new();
let mut throwaway = 0;
for _ in 0..SAMPLES {
let f = loop {
let f = $ty::from_bits(rng.gen());
if f.is_finite() {
break f;
}
};
let t1 = std::time::SystemTime::now();
for _ in 0..ITERATIONS {
throwaway += ryu::Buffer::new().format_finite(f).len();
}
let duration = t1.elapsed().unwrap();
let nanos = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64;
mv.update(nanos as f64 / ITERATIONS as f64);
}
println!(
"{:12} {:8.3} {:8.3}",
concat!(stringify!($name), ":"),
mv.mean,
mv.stddev(),
);
throwaway
}
};
}
benchmark!(pretty32, f32);
benchmark!(pretty64, f64);
fn main() {
println!("{:>20}{:>9}", "Average", "Stddev");
let mut throwaway = 0;
throwaway += pretty32();
throwaway += pretty64();
if std::env::var_os("ryu-benchmark").is_some() {
// Prevent the compiler from optimizing the code away.
println!("{}", throwaway);
}
}