sorting_race/models/
metrics.rs1#[derive(Debug, Clone, Default)]
5pub struct Metrics {
6 pub comparisons: u64,
8 pub moves: u64,
10 pub execution_time_us: u64,
12 pub peak_memory_bytes: usize,
14 pub current_memory_bytes: usize,
16 pub steps: usize,
18 pub array_accesses: u64,
20 pub recursive_calls: u64,
22}
23
24impl Metrics {
25 pub fn new() -> Self {
27 Self::default()
28 }
29
30 pub fn reset(&mut self) {
32 *self = Self::default();
33 }
34
35 pub fn add_comparisons(&mut self, count: u64) {
37 self.comparisons += count;
38 }
39
40 pub fn add_moves(&mut self, count: u64) {
42 self.moves += count;
43 }
44
45 pub fn add_time(&mut self, microseconds: u64) {
47 self.execution_time_us += microseconds;
48 }
49
50 pub fn update_memory(&mut self, current: usize) {
52 self.current_memory_bytes = current;
53 self.peak_memory_bytes = self.peak_memory_bytes.max(current);
54 }
55
56 pub fn increment_steps(&mut self) {
58 self.steps += 1;
59 }
60
61 pub fn add_array_accesses(&mut self, count: u64) {
63 self.array_accesses += count;
64 }
65
66 pub fn add_recursive_calls(&mut self, count: u64) {
68 self.recursive_calls += count;
69 }
70
71 pub fn ops_per_second(&self) -> f64 {
73 if self.execution_time_us == 0 {
74 0.0
75 } else {
76 let total_ops = self.comparisons + self.moves;
77 (total_ops as f64 * 1_000_000.0) / self.execution_time_us as f64
78 }
79 }
80
81 pub fn avg_step_time_us(&self) -> f64 {
83 if self.steps == 0 {
84 0.0
85 } else {
86 self.execution_time_us as f64 / self.steps as f64
87 }
88 }
89
90 pub fn memory_efficiency(&self) -> f64 {
92 if self.peak_memory_bytes == 0 {
93 1.0
94 } else {
95 self.current_memory_bytes as f64 / self.peak_memory_bytes as f64
96 }
97 }
98}
99
100#[derive(Debug, Clone)]
102pub struct MetricsSnapshot {
103 pub metrics: Metrics,
105 pub timestamp_us: u64,
107 pub algorithm_name: String,
109}
110
111impl MetricsSnapshot {
112 pub fn new(metrics: Metrics, timestamp_us: u64, algorithm_name: String) -> Self {
114 Self {
115 metrics,
116 timestamp_us,
117 algorithm_name,
118 }
119 }
120}