sorting_race/models/
metrics.rs

1//! Performance metrics tracking for sorting algorithms
2
3/// Comprehensive metrics for algorithm performance
4#[derive(Debug, Clone, Default)]
5pub struct Metrics {
6    /// Total number of comparisons performed
7    pub comparisons: u64,
8    /// Total number of element moves/swaps performed
9    pub moves: u64,
10    /// Total execution time in microseconds
11    pub execution_time_us: u64,
12    /// Peak memory usage in bytes
13    pub peak_memory_bytes: usize,
14    /// Current memory usage in bytes
15    pub current_memory_bytes: usize,
16    /// Number of algorithm steps executed
17    pub steps: usize,
18    /// Array access count (reads + writes)
19    pub array_accesses: u64,
20    /// Number of recursive calls made
21    pub recursive_calls: u64,
22}
23
24impl Metrics {
25    /// Create a new metrics instance
26    pub fn new() -> Self {
27        Self::default()
28    }
29
30    /// Reset all metrics to zero
31    pub fn reset(&mut self) {
32        *self = Self::default();
33    }
34
35    /// Add comparison count
36    pub fn add_comparisons(&mut self, count: u64) {
37        self.comparisons += count;
38    }
39
40    /// Add move count
41    pub fn add_moves(&mut self, count: u64) {
42        self.moves += count;
43    }
44
45    /// Add execution time
46    pub fn add_time(&mut self, microseconds: u64) {
47        self.execution_time_us += microseconds;
48    }
49
50    /// Update memory usage
51    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    /// Increment step counter
57    pub fn increment_steps(&mut self) {
58        self.steps += 1;
59    }
60
61    /// Add array access count
62    pub fn add_array_accesses(&mut self, count: u64) {
63        self.array_accesses += count;
64    }
65
66    /// Add recursive call count
67    pub fn add_recursive_calls(&mut self, count: u64) {
68        self.recursive_calls += count;
69    }
70
71    /// Calculate operations per second
72    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    /// Calculate average time per step
82    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    /// Get memory efficiency ratio
91    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/// Snapshot of metrics at a point in time
101#[derive(Debug, Clone)]
102pub struct MetricsSnapshot {
103    /// The metrics data
104    pub metrics: Metrics,
105    /// Timestamp when snapshot was taken
106    pub timestamp_us: u64,
107    /// Algorithm name
108    pub algorithm_name: String,
109}
110
111impl MetricsSnapshot {
112    /// Create a new metrics snapshot
113    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}