use std::time::Instant;
#[inline]
pub fn test_performance(f: &dyn Fn(), sample_size: usize) {
let mut times = vec![];
for _ in 0..sample_size {
let start = Instant::now();
f();
let duration = start.elapsed();
times.push(duration.as_nanos() as f64 / 1E9);
}
let min_time = times.iter().fold(f64::INFINITY, |a, &b| a.min(b));
let max_time = times.iter().fold(0_f64, |a, &b| a.max(b));
let range = max_time - min_time;
let average = times.iter().fold(0.0, |acc, t| acc + t) / sample_size as f64;
let variance = times.iter().fold(0.0, |acc, t| acc + (t - average).powf(2.0)) / (sample_size - 1) as f64;
let std_dev = variance.sqrt();
let median = median(×);
let iqr = iqr(×);
println!(
"Performance Test:
Number of samples: {}
Minimum time (s): {}
Maximum time (s): {}
Range: {}
Average time (s): {}
Variance: {}
Standard deviation: {}
Median: {}
Interquartile range: {}
", sample_size, min_time, max_time, range, average, variance, std_dev, median, iqr);
}
#[inline]
fn median(vec: &Vec<f64>) -> f64 {
if (vec.len() % 2) == 0 {
let idx_left = vec.len() / 2 - 1;
let idx_right = vec.len() / 2;
(vec[idx_left] + vec[idx_right]) as f64 / 2.0
}
else {
vec[(vec.len() / 2)] as f64
}
}
#[inline]
fn iqr(vec: &Vec<f64>) -> f64{
let mut temp;
let tup = if (vec.len() % 2) == 0 {
vec.split_at(vec.len() / 2)
}
else {
temp = vec.clone();
temp.remove(temp.len() / 2);
temp.split_at(temp.len() / 2)
};
let q1 = median(&tup.0.to_vec());
let q3 = median(&tup.1.to_vec());
(q3 - q1).abs()
}
#[test]
fn test_median() {
assert_eq!(median(&vec![0.0, 3.0, 5.0, 6.5, 6.0, 7.0, 8.0, 7.5]), 6.25);
}
#[test]
fn test_iqr() {
assert_eq!(iqr(&vec![0.0, 3.0, 5.0, 6.5, 6.0, 7.0, 8.0, 7.5]), 3.5);
assert_eq!(iqr(&vec![3.0, 5.0, 6.5, 6.0, 7.0, 8.0, 7.5]), 3.0);
assert_eq!(iqr(&vec![0.1, 0.1000001, 0.1, 0.100000000001, 0.1]), 4.999950001249864E-8);
}