1use std::time::{Duration, Instant};
4
5pub mod timing_utils {
7 use super::*;
8
9 pub fn measure_time<F, R>(f: F) -> (R, Duration)
11 where
12 F: FnOnce() -> R,
13 {
14 let start = Instant::now();
15 let result = f();
16 let duration = start.elapsed();
17 (result, duration)
18 }
19
20 pub async fn measure_time_async<F, Fut, R>(f: F) -> (R, Duration)
22 where
23 F: FnOnce() -> Fut,
24 Fut: std::future::Future<Output = R>,
25 {
26 let start = Instant::now();
27 let result = f().await;
28 let duration = start.elapsed();
29 (result, duration)
30 }
31
32 pub fn format_duration(duration: Duration) -> String {
34 if duration.as_secs() > 0 {
35 format!("{:.2}s", duration.as_secs_f64())
36 } else if duration.as_millis() > 0 {
37 format!("{:.2}ms", duration.as_millis() as f64)
38 } else {
39 format!("{:.2}μs", duration.as_micros() as f64)
40 }
41 }
42}
43
44pub mod performance_utils {
46 use super::*;
47
48 pub fn calculate_throughput(operations: usize, duration: Duration) -> f64 {
50 if duration.as_secs_f64() > 0.0 {
51 operations as f64 / duration.as_secs_f64()
52 } else {
53 0.0
54 }
55 }
56
57 pub fn calculate_latency(duration: Duration, operations: usize) -> Duration {
59 if operations > 0 {
60 Duration::from_nanos(duration.as_nanos() as u64 / operations as u64)
61 } else {
62 Duration::ZERO
63 }
64 }
65
66 pub fn calculate_efficiency(
68 actual_throughput: f64,
69 theoretical_throughput: f64
70 ) -> f32 {
71 if theoretical_throughput > 0.0 {
72 (actual_throughput / theoretical_throughput) as f32
73 } else {
74 0.0
75 }
76 }
77
78 pub fn benchmark_function<F, R>(
80 f: F,
81 iterations: usize,
82 warmup_iterations: usize
83 ) -> BenchmarkResult
84 where
85 F: Fn() -> R,
86 {
87 for _ in 0..warmup_iterations {
89 let _ = f();
90 }
91
92 let mut durations = Vec::with_capacity(iterations);
94 for _ in 0..iterations {
95 let (_, duration) = timing_utils::measure_time(&f);
96 durations.push(duration);
97 }
98
99 durations.sort();
101 let min_duration = durations[0];
102 let max_duration = durations[iterations - 1];
103 let avg_duration = durations.iter().sum::<Duration>() / iterations as u32;
104 let median_duration = durations[iterations / 2];
105
106 BenchmarkResult {
107 iterations,
108 min_duration,
109 max_duration,
110 avg_duration,
111 median_duration,
112 total_duration: durations.iter().sum(),
113 }
114 }
115}
116
117#[derive(Debug, Clone)]
119pub struct BenchmarkResult {
120 pub iterations: usize,
122 pub min_duration: Duration,
124 pub max_duration: Duration,
126 pub avg_duration: Duration,
128 pub median_duration: Duration,
130 pub total_duration: Duration,
132}