miden_debug_engine/profiling/
profiler.rs1use alloc::{boxed::Box, vec::Vec};
2
3use miden_core::operations::Operation;
4
5use crate::profiling::{OutputResult, OutputWriter, ProfilerConfig, instrument::Instrument};
6
7#[derive(Default)]
11pub struct Profiler {
12 instruments: Vec<Box<dyn Instrument>>,
13 #[cfg(feature = "std")]
14 reports_dir: Option<std::path::PathBuf>,
15}
16
17impl Profiler {
18 pub fn from_config(config: ProfilerConfig) -> Self {
19 Self {
20 instruments: config.instruments,
21 #[cfg(feature = "std")]
22 reports_dir: config.reports_dir,
23 }
24 }
25
26 pub fn on_operation_execution_cycle(&mut self, op: Operation, proc: Option<&str>) {
28 for instrument in &mut self.instruments {
29 instrument.on_operation_execution_cycle(op, proc);
30 }
31 }
32
33 #[cfg(feature = "std")]
38 pub fn write_reports(&self) {
39 if self.instruments.is_empty() {
40 return;
41 }
42
43 let Some(ref reports_dir) = self.reports_dir else {
44 log::warn!("cannot write profiler reports: no reports directory configured");
45 return;
46 };
47
48 if let Err(e) = std::fs::create_dir_all(reports_dir) {
49 log::error!(
50 "failed to create profiler reports directory {}: {e}",
51 reports_dir.display()
52 );
53 return;
54 }
55
56 for instrument in &self.instruments {
57 let name = instrument.name();
58 let path = reports_dir.join(name);
59 let mut file = match std::fs::File::create(&path) {
60 Ok(file) => file,
61 Err(e) => {
62 log::error!(
63 "failed to create profiler output file for `{name}` at {}: {e}",
64 path.display()
65 );
66 continue;
67 }
68 };
69 if let Err(e) = instrument.write_report_to(&mut file) {
70 log::error!("failed to write `{name}` report to {}: {e}", path.display());
71 }
72 }
73 }
74
75 pub fn write_reports_to(&self, writer: &mut dyn OutputWriter) -> OutputResult<()> {
77 if self.instruments.is_empty() {
78 return Ok(());
79 }
80
81 for instrument in &self.instruments {
82 instrument.write_report_to(writer)?;
83 }
84 Ok(())
85 }
86}
87
88#[cfg(all(test, feature = "std"))]
89mod tests;