Skip to main content

ferrous_forge/performance/
mod.rs

1//! Performance optimizations for Ferrous Forge
2//!
3//! This module provides performance enhancements including:
4//! - Parallel validation execution
5//! - Caching strategies
6//! - Lazy file parsing
7//! - Memory pooling
8
9/// Caching strategies for validation results.
10pub mod cache;
11/// Parallel execution of validation checks.
12pub mod parallel;
13
14use std::sync::Arc;
15use std::time::Duration;
16
17/// Performance configuration
18#[derive(Debug, Clone)]
19pub struct PerformanceConfig {
20    /// Enable parallel execution
21    pub parallel_enabled: bool,
22    /// Number of worker threads (0 = auto)
23    pub thread_count: usize,
24    /// Enable caching
25    pub cache_enabled: bool,
26    /// Cache TTL in seconds
27    pub cache_ttl: Duration,
28    /// Enable lazy parsing
29    pub lazy_parsing: bool,
30    /// Memory pool size in MB
31    pub memory_pool_size: usize,
32}
33
34impl Default for PerformanceConfig {
35    fn default() -> Self {
36        Self {
37            parallel_enabled: true,
38            thread_count: 0, // Auto-detect
39            cache_enabled: true,
40            cache_ttl: Duration::from_secs(300), // 5 minutes
41            lazy_parsing: true,
42            memory_pool_size: 100, // 100MB
43        }
44    }
45}
46
47/// Performance metrics
48#[derive(Debug, Clone, Default)]
49pub struct PerformanceMetrics {
50    /// Total validation time in milliseconds
51    pub validation_time_ms: u64,
52    /// Memory usage in bytes
53    pub memory_usage_bytes: u64,
54    /// Number of files processed
55    pub files_processed: usize,
56    /// Cache hit rate (0.0 - 1.0)
57    pub cache_hit_rate: f64,
58    /// Parallel speedup factor
59    pub parallel_speedup: f64,
60}
61
62impl PerformanceMetrics {
63    /// Check if performance targets are met
64    pub fn meets_targets(&self) -> bool {
65        self.validation_time_ms < 2000 // < 2s
66            && self.memory_usage_bytes < 100 * 1024 * 1024 // < 100MB
67    }
68
69    /// Generate performance report
70    pub fn report(&self) -> String {
71        format!(
72            "Performance Metrics:\n\
73             - Validation time: {}ms\n\
74             - Memory usage: {:.2}MB\n\
75             - Files processed: {}\n\
76             - Cache hit rate: {:.1}%\n\
77             - Parallel speedup: {:.2}x",
78            self.validation_time_ms,
79            self.memory_usage_bytes as f64 / (1024.0 * 1024.0),
80            self.files_processed,
81            self.cache_hit_rate * 100.0,
82            self.parallel_speedup
83        )
84    }
85}
86
87/// Performance monitor
88pub struct PerformanceMonitor {
89    #[allow(dead_code)]
90    config: Arc<PerformanceConfig>,
91    metrics: Arc<dashmap::DashMap<String, PerformanceMetrics>>,
92}
93
94impl PerformanceMonitor {
95    /// Create a new performance monitor
96    pub fn new(config: PerformanceConfig) -> Self {
97        Self {
98            config: Arc::new(config),
99            metrics: Arc::new(dashmap::DashMap::new()),
100        }
101    }
102
103    /// Start monitoring a task
104    pub fn start_task(&self, task_name: &str) -> TaskMonitor {
105        TaskMonitor::new(task_name.to_string(), self.metrics.clone())
106    }
107
108    /// Get metrics for a task
109    pub fn get_metrics(&self, task_name: &str) -> Option<PerformanceMetrics> {
110        self.metrics.get(task_name).map(|m| m.clone())
111    }
112
113    /// Get all metrics
114    pub fn all_metrics(&self) -> Vec<(String, PerformanceMetrics)> {
115        self.metrics
116            .iter()
117            .map(|entry| (entry.key().clone(), entry.value().clone()))
118            .collect()
119    }
120}
121
122/// Task-specific performance monitor
123pub struct TaskMonitor {
124    task_name: String,
125    start_time: std::time::Instant,
126    metrics_map: Arc<dashmap::DashMap<String, PerformanceMetrics>>,
127}
128
129impl TaskMonitor {
130    fn new(
131        task_name: String,
132        metrics_map: Arc<dashmap::DashMap<String, PerformanceMetrics>>,
133    ) -> Self {
134        Self {
135            task_name,
136            start_time: std::time::Instant::now(),
137            metrics_map,
138        }
139    }
140
141    /// Complete the task and record metrics
142    pub fn complete(self, files_processed: usize) {
143        let elapsed = self.start_time.elapsed();
144        let metrics = PerformanceMetrics {
145            validation_time_ms: elapsed.as_millis() as u64,
146            memory_usage_bytes: estimate_memory_usage(),
147            files_processed,
148            cache_hit_rate: 0.0,   // Will be updated by cache module
149            parallel_speedup: 1.0, // Will be updated by parallel module
150        };
151        self.metrics_map.insert(self.task_name, metrics);
152    }
153}
154
155/// Estimate current memory usage
156fn estimate_memory_usage() -> u64 {
157    // This is a simplified estimation
158    // In production, we'd use more sophisticated memory tracking
159
160    // For now, use a simple heuristic based on thread count
161    let thread_count = rayon::current_num_threads();
162    let base_memory = 20 * 1024 * 1024; // 20MB base
163    let per_thread = 5 * 1024 * 1024; // 5MB per thread
164
165    base_memory + (thread_count as u64 * per_thread)
166}
167
168#[cfg(test)]
169mod tests {
170    use super::*;
171
172    #[test]
173    fn test_performance_config_default() {
174        let config = PerformanceConfig::default();
175        assert!(config.parallel_enabled);
176        assert!(config.cache_enabled);
177        assert_eq!(config.thread_count, 0);
178    }
179
180    #[test]
181    fn test_performance_metrics() {
182        let metrics = PerformanceMetrics {
183            validation_time_ms: 1500,
184            memory_usage_bytes: 50 * 1024 * 1024,
185            ..Default::default()
186        };
187
188        assert!(metrics.meets_targets());
189
190        let metrics = PerformanceMetrics {
191            validation_time_ms: 3000,
192            memory_usage_bytes: 50 * 1024 * 1024,
193            ..Default::default()
194        };
195        assert!(!metrics.meets_targets());
196    }
197
198    #[test]
199    fn test_performance_monitor() {
200        let config = PerformanceConfig::default();
201        let monitor = PerformanceMonitor::new(config);
202
203        let task = monitor.start_task("test_task");
204        task.complete(10);
205
206        let metrics = monitor.get_metrics("test_task");
207        assert!(metrics.is_some());
208    }
209}