dda_rs/
profiling.rs

1use std::fs::OpenOptions;
2use std::io::Write;
3use std::path::PathBuf;
4use std::time::Instant;
5
6/// Profiling/benchmarking infrastructure for performance measurement
7pub struct ProfileScope {
8    label: String,
9    start: Instant,
10}
11
12impl ProfileScope {
13    pub fn new(label: impl Into<String>) -> Self {
14        Self {
15            label: label.into(),
16            start: Instant::now(),
17        }
18    }
19}
20
21impl Drop for ProfileScope {
22    fn drop(&mut self) {
23        let elapsed = self.start.elapsed();
24
25        log::info!(
26            "[PROFILE] {} - {:.3}ms",
27            self.label,
28            elapsed.as_secs_f64() * 1000.0
29        );
30
31        // Also write to file
32        if let Err(e) = write_profile_log(&self.label, elapsed.as_secs_f64() * 1000.0) {
33            log::warn!("Failed to write profile log: {}", e);
34        }
35    }
36}
37
38fn get_profile_log_path() -> PathBuf {
39    let app_dir = dirs::data_local_dir()
40        .unwrap_or_else(|| PathBuf::from("."))
41        .join("DDALAB");
42
43    std::fs::create_dir_all(&app_dir).ok();
44    app_dir.join("performance_profile.log")
45}
46
47fn write_profile_log(label: &str, duration_ms: f64) -> std::io::Result<()> {
48    let log_path = get_profile_log_path();
49    let mut file = OpenOptions::new()
50        .create(true)
51        .append(true)
52        .open(log_path)?;
53
54    let timestamp = chrono::Utc::now().to_rfc3339();
55    writeln!(file, "{} | {} | {:.3}ms", timestamp, label, duration_ms)?;
56
57    Ok(())
58}
59
60/// Macro for easy profiling
61#[macro_export]
62macro_rules! profile_scope {
63    ($label:expr) => {
64        let _profile_scope = $crate::profiling::ProfileScope::new($label);
65    };
66}
67
68/// Helper to get profile log location for user
69pub fn get_profile_log_location() -> String {
70    get_profile_log_path()
71        .to_str()
72        .unwrap_or("Unknown")
73        .to_string()
74}