scirs2_core/profiling/
mod.rs1pub mod advanced;
56pub mod comprehensive;
57pub mod entries;
58pub mod memory;
59pub mod profiler;
60pub mod timer;
61
62pub mod adaptive;
64pub mod continuousmonitoring;
65pub mod coverage;
66pub mod dashboards;
67pub mod flame_graph_svg;
68pub mod hardware_counters;
69pub mod performance_hints;
70pub mod production;
71pub mod system_monitor;
72
73pub mod instrumentation;
75pub mod memory_profiling;
76pub mod opentelemetry_integration;
77pub mod perf_integration;
78pub mod prometheus_metrics;
79pub mod tracing_framework;
80
81pub mod tracy;
85
86pub use entries::{MemoryEntry, TimingEntry};
88pub use memory::{profiling_memory_tracker, MemoryTracker};
89pub use profiler::Profiler;
90pub use timer::Timer;
91pub use tracy::{TracyClient, TracySpan};
92
93pub use advanced::{
95 BottleneckConfig, BottleneckDetector, BottleneckReport, BottleneckType, DifferentialProfiler,
96 DifferentialReport, ExportableProfiler, FlameGraphGenerator, FlameGraphNode, MemoryDiff,
97 PerformanceChange, PerformanceStats, ProfileSnapshot, ResourceStats, SystemResourceMonitor,
98 TimingDiff,
99};
100
101pub use comprehensive::{ComprehensiveConfig, ComprehensiveProfiler, ComprehensiveReport};
103
104pub use tracing_framework::{init_tracing, TracingConfig};
106#[cfg(feature = "profiling_advanced")]
107pub use tracing_framework::{PerfZone, SpanGuard, TracingFormat};
108
109#[cfg(feature = "profiling_opentelemetry")]
110pub use opentelemetry_integration::{get_tracer, init_opentelemetry, OtelConfig};
111
112pub use instrumentation::{clear_events, record_event};
113#[cfg(feature = "instrumentation")]
114pub use instrumentation::{
115 get_all_counters, get_counter, get_events, print_counter_summary, record_event_with_duration,
116 InstrumentationEvent, InstrumentationScope, PerformanceCounter,
117};
118pub use perf_integration::PerfCounter;
119pub use perf_integration::PerfEvent;
120#[cfg(all(target_os = "linux", feature = "profiling_perf"))]
121pub use perf_integration::{PerfCounterGroup, PerfMarker};
122pub use prometheus_metrics::MetricsRegistry;
123#[cfg(feature = "profiling_prometheus")]
124pub use prometheus_metrics::{
125 latency_buckets, register_counter, register_counter_vec, register_gauge, register_gauge_vec,
126 register_histogram, register_histogram_vec, size_buckets, PrometheusTimer, SciRS2Metrics,
127};
128
129#[cfg(feature = "profiling_memory")]
130pub use memory_profiling::{disable_profiling, AllocationAnalysis, AllocationTracker, MemoryDelta};
131pub use memory_profiling::{enable_profiling, MemoryProfiler, MemoryStats};
132
133#[macro_export]
135macro_rules! profile_time {
136 ($name:expr, $body:block) => {{
137 let timer = $crate::profiling::Timer::start($name);
138 let result = $body;
139 timer.stop();
140 result
141 }};
142}
143
144#[macro_export]
146macro_rules! profile_memory {
147 ($name:expr, $body:block) => {{
148 let tracker = $crate::profiling::MemoryTracker::start($name);
149 let result = $body;
150 tracker.stop();
151 result
152 }};
153}
154
155#[macro_export]
157macro_rules! profile_time_with_parent {
158 ($name:expr, $parent:expr, $body:block) => {{
159 let timer = $crate::profiling::Timer::start_with_parent($name, $parent);
160 let result = $body;
161 timer.stop();
162 result
163 }};
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169 use std::thread;
170 use std::time::Duration;
171
172 #[test]
173 fn test_timer_basic() {
174 let timer = Timer::start("test_operation");
175 thread::sleep(Duration::from_millis(10));
176 timer.stop();
177
178 let elapsed = timer.elapsed();
179 assert!(elapsed >= Duration::from_millis(10));
180 }
181
182 #[test]
183 fn test_memory_tracker_basic() {
184 let tracker = MemoryTracker::start("test_memory");
185 tracker.stop();
186 }
188
189 #[test]
190 fn test_profiler_integration() {
191 Profiler::global().lock().expect("Operation failed").start();
193
194 let timer = Timer::start("integration_test");
195 thread::sleep(Duration::from_millis(5));
196 timer.stop();
197
198 let stats = Profiler::global()
199 .lock()
200 .expect("Operation failed")
201 .get_timing_stats("integration_test");
202 assert!(stats.is_some());
203
204 let (calls, total, avg, max) = stats.expect("Operation failed");
205 assert_eq!(calls, 1);
206 assert!(total >= Duration::from_millis(5));
207 assert!(avg >= Duration::from_millis(5));
208 assert!(max >= Duration::from_millis(5));
209 }
210
211 #[test]
212 fn test_flame_graph_generator() {
213 let mut generator = advanced::FlameGraphGenerator::new();
214
215 generator.start_call("function_a");
216 generator.start_call("function_b");
217 thread::sleep(Duration::from_millis(1));
218 generator.end_call();
219 generator.end_call();
220
221 let flame_graph = generator.generate();
222 assert!(!flame_graph.children.is_empty());
223 }
224
225 #[test]
226 fn test_bottleneck_detector() {
227 Profiler::global().lock().expect("Operation failed").start();
229
230 let timer = Timer::start("slow_operation");
232 thread::sleep(Duration::from_millis(200));
233 timer.stop();
234
235 let config = advanced::BottleneckConfig {
236 min_execution_threshold: Duration::from_millis(100),
237 min_calls: 1, ..Default::default()
239 };
240
241 let mut detector = advanced::BottleneckDetector::new(config);
242 let reports = detector.analyze(&Profiler::global().lock().expect("Operation failed"));
243
244 assert!(!reports.is_empty());
245 assert_eq!(
246 reports[0].bottleneck_type,
247 advanced::BottleneckType::SlowExecution
248 );
249 }
250
251 #[test]
252 fn test_differential_profiler() {
253 Profiler::global().lock().expect("Operation failed").start();
255
256 let timer = Timer::start("diff_test_operation");
258 thread::sleep(Duration::from_millis(10));
259 timer.stop();
260
261 let mut diff_profiler = advanced::DifferentialProfiler::new();
262 diff_profiler.setbaseline(
263 &Profiler::global().lock().expect("Operation failed"),
264 Some("baseline".to_string()),
265 );
266
267 let timer = Timer::start("diff_test_operation");
269 thread::sleep(Duration::from_millis(20));
270 timer.stop();
271
272 diff_profiler.set_current(
273 &Profiler::global().lock().expect("Operation failed"),
274 Some("current".to_string()),
275 );
276
277 let report = diff_profiler.generate_diff_report();
278 assert!(report.is_some());
279
280 let report = report.expect("Operation failed");
281 assert!(!report.timing_diffs.is_empty() || !report.memory_diffs.is_empty());
282 }
284
285 #[test]
286 fn test_system_resourcemonitor() {
287 let monitor = advanced::SystemResourceMonitor::new(Duration::from_millis(10));
288 monitor.start();
289
290 thread::sleep(Duration::from_millis(50));
291 monitor.stop();
292
293 let stats = monitor.get_stats();
294 assert!(stats.sample_count > 0);
295 }
296
297 #[test]
298 fn test_exportable_profiler() {
299 let mut profiler = advanced::ExportableProfiler::new();
300 profiler.add_metadata("test_run".to_string(), "beta2".to_string());
301
302 profiler.profiler().start();
303
304 let timer = Timer::start("export_test");
305 thread::sleep(Duration::from_millis(5));
306 timer.stop();
307
308 let csv_path = std::env::temp_dir().join("test_profile.csv");
311 let csv_result =
312 profiler.export_to_csv(csv_path.to_str().unwrap_or("/tmp/test_profile.csv"));
313 drop(csv_result);
315 }
316}