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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! Data structures for profiling entries (timing and memory)
use std::time::Duration;
/// Timing entry for the profiler
#[derive(Debug, Clone)]
pub struct TimingEntry {
/// Number of calls
calls: usize,
/// Total duration
total_duration: Duration,
/// Minimum duration
min_duration: Duration,
/// Maximum duration
max_duration: Duration,
/// Parent operation (used for hierarchical profiling structure)
#[allow(dead_code)]
parent: Option<String>,
/// Child operations
children: Vec<String>,
}
impl TimingEntry {
/// Create a new timing entry
pub fn new(duration: Duration, parent: Option<&str>) -> Self {
Self {
calls: 1,
total_duration: duration,
min_duration: duration,
max_duration: duration,
parent: parent.map(String::from),
children: Vec::new(),
}
}
/// Add a new timing measurement
pub fn add_measurement(&mut self, duration: Duration) {
self.calls += 1;
self.total_duration += duration;
self.min_duration = std::cmp::min(self.min_duration, duration);
self.max_duration = std::cmp::max(self.max_duration, duration);
}
/// Add a child operation
pub fn add_child(&mut self, child: &str) {
if !self.children.contains(&child.to_string()) {
self.children.push(child.to_string());
}
}
/// Get the average duration
pub fn average_duration(&self) -> Duration {
if self.calls == 0 {
Duration::from_secs(0)
} else {
self.total_duration / self.calls as u32
}
}
/// Get the number of calls
pub fn calls(&self) -> usize {
self.calls
}
/// Get the total duration
pub fn total_duration(&self) -> Duration {
self.total_duration
}
/// Get the minimum duration
pub fn min_duration(&self) -> Duration {
self.min_duration
}
/// Get the maximum duration
pub fn max_duration(&self) -> Duration {
self.max_duration
}
/// Get the parent operation name
pub fn parent(&self) -> Option<&str> {
self.parent.as_deref()
}
/// Get the child operations
pub fn children(&self) -> &[String] {
&self.children
}
}
/// Memory tracking entry for the profiler
#[derive(Debug, Clone)]
pub struct MemoryEntry {
/// Number of allocations
allocations: usize,
/// Total memory delta (can be negative for memory releases)
total_delta: isize,
/// Maximum memory delta in a single allocation
max_delta: usize,
}
impl MemoryEntry {
/// Create a new memory entry
pub fn new(delta: usize) -> Self {
Self {
allocations: 1,
total_delta: delta as isize,
max_delta: delta,
}
}
/// Add a new memory measurement
pub fn add_measurement(&mut self, delta: usize) {
self.allocations += 1;
self.total_delta += delta as isize;
self.max_delta = std::cmp::max(self.max_delta, delta);
}
/// Get the average memory delta
pub fn average_delta(&self) -> f64 {
if self.allocations == 0 {
0.0
} else {
self.total_delta as f64 / self.allocations as f64
}
}
/// Get the number of allocations
pub fn allocations(&self) -> usize {
self.allocations
}
/// Get the total memory delta
pub fn total_delta(&self) -> isize {
self.total_delta
}
/// Get the maximum memory delta
pub fn max_delta(&self) -> usize {
self.max_delta
}
}