Skip to content

Instantly share code, notes, and snippets.

@jneem
Created February 24, 2022 22:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jneem/d1ea09dc4ad12894bebb69be5eb3e36f to your computer and use it in GitHub Desktop.
Save jneem/d1ea09dc4ad12894bebb69be5eb3e36f to your computer and use it in GitHub Desktop.
#![feature(bench_black_box)]
use rand::rngs::SmallRng;
use rand::{Rng, SeedableRng};
use std::hint::black_box;
use std::time::{Duration, Instant};
fn main() {
for error_rate in [0, 1, 10, 100] {
println!(
"sqrt {}: {:?}",
error_rate,
sqrt_test(error_rate as f64 / 1000.0, 9999)
);
}
for error_rate in [0, 1, 10, 100] {
println!(
"fib {}: {:?}",
error_rate,
fib_test(error_rate as f64 / 1000.0, 9999)
);
}
}
fn do_sqrt(values: &[f64]) -> Result<(), ()> {
for &v in values {
if v < 0.0 {
return Err(());
}
let _ = black_box(v.sqrt());
}
Ok(())
}
fn result_sqrt(values: &[f64], repeat: u64) -> u64 {
let mut failures = 0;
for _ in 0..repeat {
if do_sqrt(values).is_err() {
failures += 1;
}
}
failures
}
fn do_fib(n: u64, max_depth: u64) -> Result<u64, ()> {
if max_depth == 0 {
return Err(());
}
if n <= 2 {
return Ok(1);
}
let n2 = do_fib(n - 2, max_depth - 1)?;
let n1 = do_fib(n - 1, max_depth - 1)?;
Ok(n1 + n2)
}
fn result_fib(n: u64, max_depth: u64) -> u64 {
do_fib(n, max_depth).unwrap_or(0)
}
fn sqrt_test(error_rate: f64, seed: u64) -> Duration {
let repeat = 10000;
let inner_repeat = 10;
let mut rng = SmallRng::seed_from_u64(seed);
// Prepare an array of values.
let mut values = vec![1.0; 100];
let mut result = 0;
let start = Instant::now();
for _ in 0..repeat {
if rng.gen_bool(error_rate) {
values[10] = -1.0;
}
result += result_sqrt(&values, inner_repeat);
values[10] = 1.0;
}
if result > inner_repeat * repeat {
println!("invalid result!");
}
Instant::now().duration_since(start)
}
fn fib_test(error_rate: f64, seed: u64) -> Duration {
let repeat = 10000;
let depth = 15;
let expected = 610;
let mut rng = SmallRng::seed_from_u64(seed);
let mut result = 0;
let start = Instant::now();
for _ in 0..repeat {
let max_depth = if rng.gen_bool(error_rate) {
depth - 2
} else {
depth + 1
};
result += (result_fib(depth, max_depth) == expected) as u64;
}
if result > 0 {
println!("invalid result!");
}
Instant::now().duration_since(start)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment