use std::time::{Duration, Instant};
pub mod timing_utils {
use super::*;
pub fn measure_time<F, R>(f: F) -> (R, Duration)
where
F: FnOnce() -> R,
{
let start = Instant::now();
let result = f();
let duration = start.elapsed();
(result, duration)
}
pub async fn measure_time_async<F, Fut, R>(f: F) -> (R, Duration)
where
F: FnOnce() -> Fut,
Fut: std::future::Future<Output = R>,
{
let start = Instant::now();
let result = f().await;
let duration = start.elapsed();
(result, duration)
}
pub fn format_duration(duration: Duration) -> String {
if duration.as_secs() > 0 {
format!("{:.2}s", duration.as_secs_f64())
} else if duration.as_millis() > 0 {
format!("{:.2}ms", duration.as_millis() as f64)
} else {
format!("{:.2}μs", duration.as_micros() as f64)
}
}
}
pub mod performance_utils {
use super::*;
pub fn calculate_throughput(operations: usize, duration: Duration) -> f64 {
if duration.as_secs_f64() > 0.0 {
operations as f64 / duration.as_secs_f64()
} else {
0.0
}
}
pub fn calculate_latency(duration: Duration, operations: usize) -> Duration {
if operations > 0 {
Duration::from_nanos(duration.as_nanos() as u64 / operations as u64)
} else {
Duration::ZERO
}
}
pub fn calculate_efficiency(actual_throughput: f64, theoretical_throughput: f64) -> f32 {
if theoretical_throughput > 0.0 {
(actual_throughput / theoretical_throughput) as f32
} else {
0.0
}
}
pub fn benchmark_function<F, R>(
f: F,
iterations: usize,
warmup_iterations: usize,
) -> BenchmarkResult
where
F: Fn() -> R,
{
for _ in 0..warmup_iterations {
let _ = f();
}
let mut durations = Vec::with_capacity(iterations);
for _ in 0..iterations {
let (_, duration) = timing_utils::measure_time(&f);
durations.push(duration);
}
durations.sort();
let min_duration = durations[0];
let max_duration = durations[iterations - 1];
let avg_duration = durations.iter().sum::<Duration>() / iterations as u32;
let median_duration = durations[iterations / 2];
BenchmarkResult {
iterations,
min_duration,
max_duration,
avg_duration,
median_duration,
total_duration: durations.iter().sum(),
}
}
}
#[derive(Debug, Clone)]
pub struct BenchmarkResult {
pub iterations: usize,
pub min_duration: Duration,
pub max_duration: Duration,
pub avg_duration: Duration,
pub median_duration: Duration,
pub total_duration: Duration,
}