quantrs2_sim/jit_compilation/
profiler.rs

1//! Runtime profiling for JIT compilation
2//!
3//! This module provides runtime profiling and statistics tracking.
4
5use std::collections::VecDeque;
6use std::time::Duration;
7
8/// Runtime profiler for performance monitoring
9pub struct RuntimeProfiler {
10    /// Execution time tracking
11    execution_times: VecDeque<Duration>,
12    /// Memory usage tracking
13    memory_usage: VecDeque<usize>,
14    /// Performance statistics
15    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    /// Record execution time
35    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    /// Record memory usage
44    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    /// Update performance statistics
53    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    /// Get current statistics
82    #[must_use]
83    pub const fn get_stats(&self) -> &RuntimeProfilerStats {
84        &self.stats
85    }
86}
87
88/// Runtime profiler statistics
89#[derive(Debug, Clone)]
90pub struct RuntimeProfilerStats {
91    /// Average execution time
92    pub average_execution_time: Duration,
93    /// Minimum execution time
94    pub min_execution_time: Duration,
95    /// Maximum execution time
96    pub max_execution_time: Duration,
97    /// Average memory usage
98    pub average_memory_usage: usize,
99    /// Peak memory usage
100    pub peak_memory_usage: usize,
101    /// Number of samples
102    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/// JIT compiler statistics
119#[derive(Debug, Clone)]
120pub struct JITCompilerStats {
121    /// Total number of compilations
122    pub total_compilations: usize,
123    /// Total compilation time
124    pub total_compilation_time: Duration,
125    /// Number of cache hits
126    pub cache_hits: usize,
127    /// Number of cache misses
128    pub cache_misses: usize,
129    /// Number of cache clears
130    pub cache_clears: usize,
131    /// Average compilation time
132    pub average_compilation_time: Duration,
133    /// Total patterns analyzed
134    pub patterns_analyzed: usize,
135    /// Successful compilations
136    pub successful_compilations: usize,
137    /// Failed compilations
138    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/// JIT simulator statistics
158#[derive(Debug, Clone)]
159pub struct JITSimulatorStats {
160    /// Number of compiled executions
161    pub compiled_executions: usize,
162    /// Number of interpreted executions
163    pub interpreted_executions: usize,
164    /// Total time spent in compiled execution
165    pub total_compiled_time: Duration,
166    /// Total time spent in interpreted execution
167    pub total_interpreted_time: Duration,
168    /// JIT compilation speedup factor
169    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    /// Update speedup factor
186    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}