Created
February 24, 2022 22:23
-
-
Save jneem/d1ea09dc4ad12894bebb69be5eb3e36f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![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