quantrs2_sim/jit_compilation/
profiler.rs1use std::collections::VecDeque;
6use std::time::Duration;
7
8pub struct RuntimeProfiler {
10 execution_times: VecDeque<Duration>,
12 memory_usage: VecDeque<usize>,
14 stats: RuntimeProfilerStats,
16}
17
18impl Default for RuntimeProfiler {
19 fn default() -> Self {
20 Self::new()
21 }
22}
23
24impl RuntimeProfiler {
25 #[must_use]
26 pub fn new() -> Self {
27 Self {
28 execution_times: VecDeque::new(),
29 memory_usage: VecDeque::new(),
30 stats: RuntimeProfilerStats::default(),
31 }
32 }
33
34 pub fn record_execution_time(&mut self, duration: Duration) {
36 self.execution_times.push_back(duration);
37 if self.execution_times.len() > 1000 {
38 self.execution_times.pop_front();
39 }
40 self.update_stats();
41 }
42
43 pub fn record_memory_usage(&mut self, usage: usize) {
45 self.memory_usage.push_back(usage);
46 if self.memory_usage.len() > 1000 {
47 self.memory_usage.pop_front();
48 }
49 self.update_stats();
50 }
51
52 fn update_stats(&mut self) {
54 if !self.execution_times.is_empty() {
55 let total_time: Duration = self.execution_times.iter().sum();
56 self.stats.average_execution_time = total_time / self.execution_times.len() as u32;
57
58 self.stats.min_execution_time = self
59 .execution_times
60 .iter()
61 .min()
62 .copied()
63 .unwrap_or(Duration::from_secs(0));
64 self.stats.max_execution_time = self
65 .execution_times
66 .iter()
67 .max()
68 .copied()
69 .unwrap_or(Duration::from_secs(0));
70 }
71
72 if !self.memory_usage.is_empty() {
73 self.stats.average_memory_usage =
74 self.memory_usage.iter().sum::<usize>() / self.memory_usage.len();
75 self.stats.peak_memory_usage = self.memory_usage.iter().max().copied().unwrap_or(0);
76 }
77
78 self.stats.sample_count = self.execution_times.len();
79 }
80
81 #[must_use]
83 pub const fn get_stats(&self) -> &RuntimeProfilerStats {
84 &self.stats
85 }
86}
87
88#[derive(Debug, Clone)]
90pub struct RuntimeProfilerStats {
91 pub average_execution_time: Duration,
93 pub min_execution_time: Duration,
95 pub max_execution_time: Duration,
97 pub average_memory_usage: usize,
99 pub peak_memory_usage: usize,
101 pub sample_count: usize,
103}
104
105impl Default for RuntimeProfilerStats {
106 fn default() -> Self {
107 Self {
108 average_execution_time: Duration::from_secs(0),
109 min_execution_time: Duration::from_secs(0),
110 max_execution_time: Duration::from_secs(0),
111 average_memory_usage: 0,
112 peak_memory_usage: 0,
113 sample_count: 0,
114 }
115 }
116}
117
118#[derive(Debug, Clone)]
120pub struct JITCompilerStats {
121 pub total_compilations: usize,
123 pub total_compilation_time: Duration,
125 pub cache_hits: usize,
127 pub cache_misses: usize,
129 pub cache_clears: usize,
131 pub average_compilation_time: Duration,
133 pub patterns_analyzed: usize,
135 pub successful_compilations: usize,
137 pub failed_compilations: usize,
139}
140
141impl Default for JITCompilerStats {
142 fn default() -> Self {
143 Self {
144 total_compilations: 0,
145 total_compilation_time: Duration::from_secs(0),
146 cache_hits: 0,
147 cache_misses: 0,
148 cache_clears: 0,
149 average_compilation_time: Duration::from_secs(0),
150 patterns_analyzed: 0,
151 successful_compilations: 0,
152 failed_compilations: 0,
153 }
154 }
155}
156
157#[derive(Debug, Clone)]
159pub struct JITSimulatorStats {
160 pub compiled_executions: usize,
162 pub interpreted_executions: usize,
164 pub total_compiled_time: Duration,
166 pub total_interpreted_time: Duration,
168 pub speedup_factor: f64,
170}
171
172impl Default for JITSimulatorStats {
173 fn default() -> Self {
174 Self {
175 compiled_executions: 0,
176 interpreted_executions: 0,
177 total_compiled_time: Duration::from_secs(0),
178 total_interpreted_time: Duration::from_secs(0),
179 speedup_factor: 1.0,
180 }
181 }
182}
183
184impl JITSimulatorStats {
185 pub fn update_speedup_factor(&mut self) {
187 if self.compiled_executions > 0 && self.interpreted_executions > 0 {
188 let avg_compiled =
189 self.total_compiled_time.as_secs_f64() / self.compiled_executions as f64;
190 let avg_interpreted =
191 self.total_interpreted_time.as_secs_f64() / self.interpreted_executions as f64;
192
193 if avg_compiled > 0.0 {
194 self.speedup_factor = avg_interpreted / avg_compiled;
195 }
196 }
197 }
198}