1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Performance metrics tracking for sorting algorithms
/// Comprehensive metrics for algorithm performance
#[derive(Debug, Clone, Default)]
pub struct Metrics {
/// Total number of comparisons performed
pub comparisons: u64,
/// Total number of element moves/swaps performed
pub moves: u64,
/// Total execution time in microseconds
pub execution_time_us: u64,
/// Peak memory usage in bytes
pub peak_memory_bytes: usize,
/// Current memory usage in bytes
pub current_memory_bytes: usize,
/// Number of algorithm steps executed
pub steps: usize,
/// Array access count (reads + writes)
pub array_accesses: u64,
/// Number of recursive calls made
pub recursive_calls: u64,
}
impl Metrics {
/// Create a new metrics instance
pub fn new() -> Self {
Self::default()
}
/// Reset all metrics to zero
pub fn reset(&mut self) {
*self = Self::default();
}
/// Add comparison count
pub fn add_comparisons(&mut self, count: u64) {
self.comparisons += count;
}
/// Add move count
pub fn add_moves(&mut self, count: u64) {
self.moves += count;
}
/// Add execution time
pub fn add_time(&mut self, microseconds: u64) {
self.execution_time_us += microseconds;
}
/// Update memory usage
pub fn update_memory(&mut self, current: usize) {
self.current_memory_bytes = current;
self.peak_memory_bytes = self.peak_memory_bytes.max(current);
}
/// Increment step counter
pub fn increment_steps(&mut self) {
self.steps += 1;
}
/// Add array access count
pub fn add_array_accesses(&mut self, count: u64) {
self.array_accesses += count;
}
/// Add recursive call count
pub fn add_recursive_calls(&mut self, count: u64) {
self.recursive_calls += count;
}
/// Calculate operations per second
pub fn ops_per_second(&self) -> f64 {
if self.execution_time_us == 0 {
0.0
} else {
let total_ops = self.comparisons + self.moves;
(total_ops as f64 * 1_000_000.0) / self.execution_time_us as f64
}
}
/// Calculate average time per step
pub fn avg_step_time_us(&self) -> f64 {
if self.steps == 0 {
0.0
} else {
self.execution_time_us as f64 / self.steps as f64
}
}
/// Get memory efficiency ratio
pub fn memory_efficiency(&self) -> f64 {
if self.peak_memory_bytes == 0 {
1.0
} else {
self.current_memory_bytes as f64 / self.peak_memory_bytes as f64
}
}
}
/// Snapshot of metrics at a point in time
#[derive(Debug, Clone)]
pub struct MetricsSnapshot {
/// The metrics data
pub metrics: Metrics,
/// Timestamp when snapshot was taken
pub timestamp_us: u64,
/// Algorithm name
pub algorithm_name: String,
}
impl MetricsSnapshot {
/// Create a new metrics snapshot
pub fn new(metrics: Metrics, timestamp_us: u64, algorithm_name: String) -> Self {
Self {
metrics,
timestamp_us,
algorithm_name,
}
}
}