ferrous_forge/performance/
mod.rs1pub mod cache;
11pub mod parallel;
13
14use std::sync::Arc;
15use std::time::Duration;
16
17#[derive(Debug, Clone)]
19pub struct PerformanceConfig {
20 pub parallel_enabled: bool,
22 pub thread_count: usize,
24 pub cache_enabled: bool,
26 pub cache_ttl: Duration,
28 pub lazy_parsing: bool,
30 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, cache_enabled: true,
40 cache_ttl: Duration::from_secs(300), lazy_parsing: true,
42 memory_pool_size: 100, }
44 }
45}
46
47#[derive(Debug, Clone, Default)]
49pub struct PerformanceMetrics {
50 pub validation_time_ms: u64,
52 pub memory_usage_bytes: u64,
54 pub files_processed: usize,
56 pub cache_hit_rate: f64,
58 pub parallel_speedup: f64,
60}
61
62impl PerformanceMetrics {
63 pub fn meets_targets(&self) -> bool {
65 self.validation_time_ms < 2000 && self.memory_usage_bytes < 100 * 1024 * 1024 }
68
69 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
87pub struct PerformanceMonitor {
89 #[allow(dead_code)]
90 config: Arc<PerformanceConfig>,
91 metrics: Arc<dashmap::DashMap<String, PerformanceMetrics>>,
92}
93
94impl PerformanceMonitor {
95 pub fn new(config: PerformanceConfig) -> Self {
97 Self {
98 config: Arc::new(config),
99 metrics: Arc::new(dashmap::DashMap::new()),
100 }
101 }
102
103 pub fn start_task(&self, task_name: &str) -> TaskMonitor {
105 TaskMonitor::new(task_name.to_string(), self.metrics.clone())
106 }
107
108 pub fn get_metrics(&self, task_name: &str) -> Option<PerformanceMetrics> {
110 self.metrics.get(task_name).map(|m| m.clone())
111 }
112
113 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
122pub 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 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, parallel_speedup: 1.0, };
151 self.metrics_map.insert(self.task_name, metrics);
152 }
153}
154
155fn estimate_memory_usage() -> u64 {
157 let thread_count = rayon::current_num_threads();
162 let base_memory = 20 * 1024 * 1024; let per_thread = 5 * 1024 * 1024; 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}