1use super::{
7 GpuMetrics, MemoryMetrics, OptimizationCategory, OptimizationRecommendation,
8 PerformanceMetrics, SynthesisMetrics, SystemMetrics,
9};
10use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12use std::time::Duration;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct OptimizerConfig {
17 pub auto_optimize: bool,
19 pub min_improvement_threshold: f64,
21 pub max_optimization_attempts: u32,
23 pub optimization_targets: Vec<OptimizationTarget>,
25 pub resource_constraints: ResourceConstraints,
27 pub aggressiveness: u8,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct OptimizationTarget {
34 pub category: OptimizationCategory,
36 pub weight: f64,
38 pub auto_optimize: bool,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct ResourceConstraints {
45 pub max_memory_mb: Option<u64>,
47 pub max_cpu_percent: Option<f64>,
49 pub max_gpu_memory_mb: Option<u64>,
51 pub min_disk_space_mb: Option<u64>,
53 pub target_latency_ms: Option<f64>,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct OptimizationResult {
60 pub applied: Vec<AppliedOptimization>,
62 pub improvement: PerformanceImprovement,
64 pub optimization_time: Duration,
66 pub success: bool,
68 pub error: Option<String>,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct AppliedOptimization {
75 pub category: OptimizationCategory,
77 pub description: String,
79 pub previous_value: String,
81 pub new_value: String,
83 pub expected_improvement: f64,
85 pub actual_improvement: Option<f64>,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct PerformanceImprovement {
92 pub cpu_improvement: f64,
94 pub memory_improvement: f64,
96 pub speed_improvement: f64,
98 pub overall_improvement: f64,
100 pub rtf_improvement: f64,
102}
103
104pub struct PerformanceOptimizer {
106 config: OptimizerConfig,
108 optimization_history: Vec<OptimizationResult>,
110 current_settings: HashMap<String, String>,
112 baseline_metrics: Option<PerformanceMetrics>,
114}
115
116impl PerformanceOptimizer {
117 pub fn new(config: OptimizerConfig) -> Self {
119 Self {
120 config,
121 optimization_history: Vec::new(),
122 current_settings: HashMap::new(),
123 baseline_metrics: None,
124 }
125 }
126
127 pub fn set_baseline(&mut self, metrics: PerformanceMetrics) {
129 self.baseline_metrics = Some(metrics);
130 }
131
132 pub async fn analyze_and_recommend(
134 &self,
135 current_metrics: &PerformanceMetrics,
136 ) -> Vec<OptimizationRecommendation> {
137 let mut recommendations = Vec::new();
138
139 for target in &self.config.optimization_targets {
141 match target.category {
142 OptimizationCategory::Memory => {
143 self.analyze_memory_optimization(
144 &mut recommendations,
145 ¤t_metrics.memory,
146 ¤t_metrics.system,
147 target.weight,
148 )
149 .await;
150 }
151 OptimizationCategory::Cpu => {
152 self.analyze_cpu_optimization(
153 &mut recommendations,
154 ¤t_metrics.system,
155 ¤t_metrics.synthesis,
156 target.weight,
157 )
158 .await;
159 }
160 OptimizationCategory::Gpu => {
161 if let Some(ref gpu_metrics) = current_metrics.gpu {
162 self.analyze_gpu_optimization(
163 &mut recommendations,
164 gpu_metrics,
165 ¤t_metrics.synthesis,
166 target.weight,
167 )
168 .await;
169 }
170 }
171 OptimizationCategory::Parallelization => {
172 self.analyze_parallelization_optimization(
173 &mut recommendations,
174 ¤t_metrics.synthesis,
175 ¤t_metrics.system,
176 target.weight,
177 )
178 .await;
179 }
180 OptimizationCategory::Caching => {
181 self.analyze_caching_optimization(
182 &mut recommendations,
183 ¤t_metrics.memory,
184 ¤t_metrics.synthesis,
185 target.weight,
186 )
187 .await;
188 }
189 OptimizationCategory::ModelOptimization => {
190 self.analyze_model_optimization(
191 &mut recommendations,
192 ¤t_metrics.synthesis,
193 ¤t_metrics.system,
194 target.weight,
195 )
196 .await;
197 }
198 _ => {
199 self.analyze_general_optimization(
201 &mut recommendations,
202 current_metrics,
203 &target.category,
204 target.weight,
205 )
206 .await;
207 }
208 }
209 }
210
211 recommendations.sort_by(|a, b| {
213 b.priority.cmp(&a.priority).then(
214 b.performance_impact
215 .partial_cmp(&a.performance_impact)
216 .unwrap_or(std::cmp::Ordering::Equal),
217 )
218 });
219
220 recommendations
221 .into_iter()
222 .filter(|r| r.performance_impact >= self.config.min_improvement_threshold)
223 .take(10) .collect()
225 }
226
227 pub async fn apply_optimizations(
229 &mut self,
230 recommendations: &[OptimizationRecommendation],
231 ) -> OptimizationResult {
232 let start_time = std::time::Instant::now();
233 let mut applied = Vec::new();
234 let mut total_improvement = 0.0;
235
236 for recommendation in recommendations {
237 let auto_optimize = self
239 .config
240 .optimization_targets
241 .iter()
242 .find(|t| t.category == recommendation.category)
243 .map(|t| t.auto_optimize)
244 .unwrap_or(false);
245
246 if !auto_optimize || !self.config.auto_optimize {
247 continue;
248 }
249
250 if let Ok(optimization) = self.apply_single_optimization(recommendation).await {
251 total_improvement += optimization.expected_improvement;
252 applied.push(optimization);
253 }
254 }
255
256 let optimization_time = start_time.elapsed();
257
258 OptimizationResult {
259 applied,
260 improvement: PerformanceImprovement {
261 cpu_improvement: total_improvement * 0.3,
262 memory_improvement: total_improvement * 0.2,
263 speed_improvement: total_improvement * 0.4,
264 overall_improvement: total_improvement,
265 rtf_improvement: total_improvement * 0.5,
266 },
267 optimization_time,
268 success: total_improvement > 0.0,
269 error: None,
270 }
271 }
272
273 async fn apply_single_optimization(
275 &mut self,
276 recommendation: &OptimizationRecommendation,
277 ) -> Result<AppliedOptimization, Box<dyn std::error::Error>> {
278 let (setting_key, previous_value, new_value) = match recommendation.category {
279 OptimizationCategory::Memory => self.apply_memory_optimization(recommendation).await?,
280 OptimizationCategory::Cpu => self.apply_cpu_optimization(recommendation).await?,
281 OptimizationCategory::Gpu => self.apply_gpu_optimization(recommendation).await?,
282 OptimizationCategory::Parallelization => {
283 self.apply_parallelization_optimization(recommendation)
284 .await?
285 }
286 OptimizationCategory::Caching => {
287 self.apply_caching_optimization(recommendation).await?
288 }
289 OptimizationCategory::ModelOptimization => {
290 self.apply_model_optimization(recommendation).await?
291 }
292 OptimizationCategory::Io => self.apply_io_optimization(recommendation).await?,
293 OptimizationCategory::Network => {
294 self.apply_network_optimization(recommendation).await?
295 }
296 OptimizationCategory::Configuration => {
297 self.apply_configuration_optimization(recommendation)
298 .await?
299 }
300 OptimizationCategory::ResourceAllocation => {
301 self.apply_resource_allocation_optimization(recommendation)
302 .await?
303 }
304 };
305
306 self.current_settings
308 .insert(setting_key.clone(), new_value.clone());
309
310 Ok(AppliedOptimization {
311 category: recommendation.category.clone(),
312 description: recommendation.recommendation.clone(),
313 previous_value,
314 new_value,
315 expected_improvement: recommendation.performance_impact,
316 actual_improvement: None, })
318 }
319
320 async fn analyze_memory_optimization(
322 &self,
323 recommendations: &mut Vec<OptimizationRecommendation>,
324 memory: &MemoryMetrics,
325 system: &SystemMetrics,
326 weight: f64,
327 ) {
328 let memory_usage_percent = (memory.heap_used as f64
329 / (system.memory_used + system.memory_available) as f64)
330 * 100.0;
331
332 if memory_usage_percent > 75.0 {
333 recommendations.push(OptimizationRecommendation {
334 category: OptimizationCategory::Memory,
335 priority: (8.0 * weight) as u8,
336 description: format!("High memory usage: {:.1}%", memory_usage_percent),
337 recommendation:
338 "Enable memory optimization: reduce batch size, enable streaming processing"
339 .to_string(),
340 expected_improvement: format!("{:.0}% memory reduction", 30.0 * weight),
341 difficulty: 2,
342 performance_impact: 0.3 * weight,
343 });
344 }
345
346 if memory.fragmentation_percent > 20.0 {
347 recommendations.push(OptimizationRecommendation {
348 category: OptimizationCategory::Memory,
349 priority: (6.0 * weight) as u8,
350 description: format!("Memory fragmentation: {:.1}%", memory.fragmentation_percent),
351 recommendation: "Enable memory pool allocation".to_string(),
352 expected_improvement: format!("{:.0}% fragmentation reduction", 50.0 * weight),
353 difficulty: 3,
354 performance_impact: 0.15 * weight,
355 });
356 }
357
358 if memory.cache_hit_rate < 60.0 {
359 recommendations.push(OptimizationRecommendation {
360 category: OptimizationCategory::Caching,
361 priority: (7.0 * weight) as u8,
362 description: format!("Low cache hit rate: {:.1}%", memory.cache_hit_rate),
363 recommendation: "Increase cache size and enable aggressive caching".to_string(),
364 expected_improvement: format!(
365 "{:.0}% cache performance improvement",
366 40.0 * weight
367 ),
368 difficulty: 2,
369 performance_impact: 0.25 * weight,
370 });
371 }
372 }
373
374 async fn analyze_cpu_optimization(
376 &self,
377 recommendations: &mut Vec<OptimizationRecommendation>,
378 system: &SystemMetrics,
379 synthesis: &SynthesisMetrics,
380 weight: f64,
381 ) {
382 if system.cpu_usage > 90.0 {
383 recommendations.push(OptimizationRecommendation {
384 category: OptimizationCategory::Cpu,
385 priority: (9.0 * weight) as u8,
386 description: format!("CPU overload: {:.1}%", system.cpu_usage),
387 recommendation:
388 "Reduce parallel threads, enable GPU acceleration, or use lower quality"
389 .to_string(),
390 expected_improvement: format!("{:.0}% CPU usage reduction", 40.0 * weight),
391 difficulty: 2,
392 performance_impact: 0.4 * weight,
393 });
394 } else if system.cpu_usage < 30.0 && synthesis.real_time_factor > 2.0 {
395 recommendations.push(OptimizationRecommendation {
396 category: OptimizationCategory::Parallelization,
397 priority: (6.0 * weight) as u8,
398 description: format!("CPU underutilization: {:.1}%", system.cpu_usage),
399 recommendation: "Increase parallel processing threads".to_string(),
400 expected_improvement: format!("{:.0}% throughput increase", 30.0 * weight),
401 difficulty: 1,
402 performance_impact: 0.3 * weight,
403 });
404 }
405
406 if synthesis.real_time_factor < 1.0 {
407 recommendations.push(OptimizationRecommendation {
408 category: OptimizationCategory::ModelOptimization,
409 priority: (8.0 * weight) as u8,
410 description: format!(
411 "Poor real-time performance: {:.2}x RTF",
412 synthesis.real_time_factor
413 ),
414 recommendation: "Use quantized models or enable GPU acceleration".to_string(),
415 expected_improvement: "Achieve real-time synthesis".to_string(),
416 difficulty: 4,
417 performance_impact: 0.5 * weight,
418 });
419 }
420 }
421
422 async fn analyze_gpu_optimization(
424 &self,
425 recommendations: &mut Vec<OptimizationRecommendation>,
426 gpu: &GpuMetrics,
427 synthesis: &SynthesisMetrics,
428 weight: f64,
429 ) {
430 if gpu.utilization < 40.0 && synthesis.real_time_factor < 2.0 {
431 recommendations.push(OptimizationRecommendation {
432 category: OptimizationCategory::Gpu,
433 priority: (7.0 * weight) as u8,
434 description: format!("Low GPU utilization: {:.1}%", gpu.utilization),
435 recommendation: "Increase batch size or use larger models".to_string(),
436 expected_improvement: format!("{:.0}% GPU utilization improvement", 50.0 * weight),
437 difficulty: 2,
438 performance_impact: 0.3 * weight,
439 });
440 }
441
442 let gpu_memory_usage = (gpu.memory_used as f64 / gpu.memory_total as f64) * 100.0;
443 if gpu_memory_usage > 85.0 {
444 recommendations.push(OptimizationRecommendation {
445 category: OptimizationCategory::Gpu,
446 priority: (8.0 * weight) as u8,
447 description: format!("High GPU memory usage: {:.1}%", gpu_memory_usage),
448 recommendation: "Reduce batch size or enable model quantization".to_string(),
449 expected_improvement: format!("{:.0}% GPU memory reduction", 30.0 * weight),
450 difficulty: 3,
451 performance_impact: 0.2 * weight,
452 });
453 }
454
455 if gpu.temperature > 80.0 {
456 recommendations.push(OptimizationRecommendation {
457 category: OptimizationCategory::Gpu,
458 priority: (9.0 * weight) as u8,
459 description: format!("High GPU temperature: {:.1}°C", gpu.temperature),
460 recommendation: "Reduce GPU workload or improve cooling".to_string(),
461 expected_improvement: "Prevent thermal throttling".to_string(),
462 difficulty: 4,
463 performance_impact: 0.25 * weight,
464 });
465 }
466 }
467
468 async fn analyze_parallelization_optimization(
470 &self,
471 recommendations: &mut Vec<OptimizationRecommendation>,
472 synthesis: &SynthesisMetrics,
473 system: &SystemMetrics,
474 weight: f64,
475 ) {
476 let available_cores = system.thread_count;
477 let estimated_utilization = system.cpu_usage / 100.0;
478
479 if estimated_utilization < 0.6 && synthesis.queue_depth > 5 {
480 recommendations.push(OptimizationRecommendation {
481 category: OptimizationCategory::Parallelization,
482 priority: (7.0 * weight) as u8,
483 description: format!(
484 "Suboptimal parallelization: {} cores available",
485 available_cores
486 ),
487 recommendation: format!(
488 "Increase worker threads to {}",
489 (available_cores as f64 * 0.8) as usize
490 ),
491 expected_improvement: format!("{:.0}% throughput improvement", 40.0 * weight),
492 difficulty: 2,
493 performance_impact: 0.35 * weight,
494 });
495 }
496
497 if synthesis.avg_synthesis_time_ms > 1000.0 && synthesis.queue_depth < 2 {
498 recommendations.push(OptimizationRecommendation {
499 category: OptimizationCategory::Parallelization,
500 priority: (6.0 * weight) as u8,
501 description: "Sequential processing detected".to_string(),
502 recommendation: "Enable batch processing for improved efficiency".to_string(),
503 expected_improvement: format!("{:.0}% processing time reduction", 25.0 * weight),
504 difficulty: 2,
505 performance_impact: 0.25 * weight,
506 });
507 }
508 }
509
510 async fn analyze_caching_optimization(
512 &self,
513 recommendations: &mut Vec<OptimizationRecommendation>,
514 memory: &MemoryMetrics,
515 synthesis: &SynthesisMetrics,
516 weight: f64,
517 ) {
518 if memory.cache_hit_rate < 70.0 {
519 recommendations.push(OptimizationRecommendation {
520 category: OptimizationCategory::Caching,
521 priority: (7.0 * weight) as u8,
522 description: format!(
523 "Low cache efficiency: {:.1}% hit rate",
524 memory.cache_hit_rate
525 ),
526 recommendation: "Increase cache size and implement model preloading".to_string(),
527 expected_improvement: format!("{:.0}% cache hit rate improvement", 30.0 * weight),
528 difficulty: 3,
529 performance_impact: 0.3 * weight,
530 });
531 }
532
533 if synthesis.avg_synthesis_time_ms > 500.0 && memory.cache_hit_rate > 80.0 {
534 recommendations.push(OptimizationRecommendation {
535 category: OptimizationCategory::Caching,
536 priority: (5.0 * weight) as u8,
537 description: "Opportunity for aggressive caching".to_string(),
538 recommendation: "Enable result caching for repeated synthesis".to_string(),
539 expected_improvement: format!("{:.0}% synthesis speed improvement", 50.0 * weight),
540 difficulty: 3,
541 performance_impact: 0.4 * weight,
542 });
543 }
544 }
545
546 async fn analyze_model_optimization(
548 &self,
549 recommendations: &mut Vec<OptimizationRecommendation>,
550 synthesis: &SynthesisMetrics,
551 system: &SystemMetrics,
552 weight: f64,
553 ) {
554 if synthesis.real_time_factor < 1.0 {
555 recommendations.push(OptimizationRecommendation {
556 category: OptimizationCategory::ModelOptimization,
557 priority: (9.0 * weight) as u8,
558 description: format!(
559 "Below real-time performance: {:.2}x",
560 synthesis.real_time_factor
561 ),
562 recommendation: "Use quantized models (INT8/FP16) for faster inference".to_string(),
563 expected_improvement: format!("{:.0}x speed improvement", 2.0 * weight),
564 difficulty: 4,
565 performance_impact: 0.6 * weight,
566 });
567 }
568
569 if synthesis.memory_per_operation_mb > 1000.0 {
570 recommendations.push(OptimizationRecommendation {
571 category: OptimizationCategory::ModelOptimization,
572 priority: (7.0 * weight) as u8,
573 description: format!(
574 "High memory per operation: {:.0} MB",
575 synthesis.memory_per_operation_mb
576 ),
577 recommendation: "Use model pruning or distillation for smaller footprint"
578 .to_string(),
579 expected_improvement: format!("{:.0}% memory reduction", 40.0 * weight),
580 difficulty: 5,
581 performance_impact: 0.3 * weight,
582 });
583 }
584
585 let memory_usage_percent =
586 (synthesis.memory_per_operation_mb * synthesis.queue_depth as f64 * 1024.0 * 1024.0)
587 / (system.memory_used + system.memory_available) as f64
588 * 100.0;
589
590 if memory_usage_percent > 50.0 {
591 recommendations.push(OptimizationRecommendation {
592 category: OptimizationCategory::ModelOptimization,
593 priority: (8.0 * weight) as u8,
594 description: "Models consuming excessive memory".to_string(),
595 recommendation: "Use smaller model variants or enable model streaming".to_string(),
596 expected_improvement: format!(
597 "{:.0}% memory efficiency improvement",
598 35.0 * weight
599 ),
600 difficulty: 4,
601 performance_impact: 0.35 * weight,
602 });
603 }
604 }
605
606 async fn analyze_general_optimization(
608 &self,
609 recommendations: &mut Vec<OptimizationRecommendation>,
610 metrics: &PerformanceMetrics,
611 category: &OptimizationCategory,
612 weight: f64,
613 ) {
614 match category {
615 OptimizationCategory::Io => {
616 if metrics.system.disk_read_bps > 50_000_000
617 || metrics.system.disk_write_bps > 50_000_000
618 {
619 recommendations.push(OptimizationRecommendation {
620 category: OptimizationCategory::Io,
621 priority: (6.0 * weight) as u8,
622 description: "High disk I/O detected".to_string(),
623 recommendation: "Use SSD storage or enable I/O optimization".to_string(),
624 expected_improvement: format!(
625 "{:.0}% I/O performance improvement",
626 40.0 * weight
627 ),
628 difficulty: 3,
629 performance_impact: 0.3 * weight,
630 });
631 }
632 }
633 OptimizationCategory::Network => {
634 if metrics.system.network_bps > 100_000_000 {
635 recommendations.push(OptimizationRecommendation {
636 category: OptimizationCategory::Network,
637 priority: (5.0 * weight) as u8,
638 description: "High network usage detected".to_string(),
639 recommendation: "Enable compression or local caching".to_string(),
640 expected_improvement: format!(
641 "{:.0}% network efficiency improvement",
642 25.0 * weight
643 ),
644 difficulty: 3,
645 performance_impact: 0.2 * weight,
646 });
647 }
648 }
649 OptimizationCategory::Configuration => {
650 recommendations.push(OptimizationRecommendation {
651 category: OptimizationCategory::Configuration,
652 priority: (4.0 * weight) as u8,
653 description: "Configuration optimization available".to_string(),
654 recommendation: "Review and optimize system configuration".to_string(),
655 expected_improvement: format!("{:.0}% overall improvement", 15.0 * weight),
656 difficulty: 2,
657 performance_impact: 0.15 * weight,
658 });
659 }
660 OptimizationCategory::ResourceAllocation => {
661 if metrics.synthesis.queue_depth > 10 {
662 recommendations.push(OptimizationRecommendation {
663 category: OptimizationCategory::ResourceAllocation,
664 priority: (7.0 * weight) as u8,
665 description: format!("High queue depth: {}", metrics.synthesis.queue_depth),
666 recommendation: "Optimize resource allocation and scheduling".to_string(),
667 expected_improvement: format!("{:.0}% latency reduction", 30.0 * weight),
668 difficulty: 3,
669 performance_impact: 0.25 * weight,
670 });
671 }
672 }
673 _ => {} }
675 }
676
677 async fn apply_memory_optimization(
679 &mut self,
680 recommendation: &OptimizationRecommendation,
681 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
682 if recommendation.description.contains("High memory usage") {
683 let key = "batch_size".to_string();
684 let previous = self
685 .current_settings
686 .get(&key)
687 .unwrap_or(&"32".to_string())
688 .clone();
689 let new_value = (previous.parse::<u32>()? / 2).to_string();
690 Ok((key, previous, new_value))
691 } else if recommendation.description.contains("fragmentation") {
692 let key = "memory_pool".to_string();
693 let previous = self
694 .current_settings
695 .get(&key)
696 .unwrap_or(&"false".to_string())
697 .clone();
698 let new_value = "true".to_string();
699 Ok((key, previous, new_value))
700 } else {
701 Err("Unknown memory optimization".into())
702 }
703 }
704
705 async fn apply_cpu_optimization(
707 &mut self,
708 recommendation: &OptimizationRecommendation,
709 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
710 if recommendation.description.contains("CPU overload") {
711 let key = "max_threads".to_string();
712 let previous = self
713 .current_settings
714 .get(&key)
715 .unwrap_or(&"8".to_string())
716 .clone();
717 let new_value = (previous.parse::<u32>()?.saturating_sub(2)).to_string();
718 Ok((key, previous, new_value))
719 } else {
720 Err("Unknown CPU optimization".into())
721 }
722 }
723
724 async fn apply_gpu_optimization(
726 &mut self,
727 recommendation: &OptimizationRecommendation,
728 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
729 if recommendation.description.contains("Low GPU utilization") {
730 let key = "gpu_batch_size".to_string();
731 let previous = self
732 .current_settings
733 .get(&key)
734 .unwrap_or(&"16".to_string())
735 .clone();
736 let new_value = (previous.parse::<u32>()? * 2).to_string();
737 Ok((key, previous, new_value))
738 } else if recommendation.description.contains("High GPU memory") {
739 let key = "gpu_batch_size".to_string();
740 let previous = self
741 .current_settings
742 .get(&key)
743 .unwrap_or(&"16".to_string())
744 .clone();
745 let new_value = (previous.parse::<u32>()? / 2).to_string();
746 Ok((key, previous, new_value))
747 } else {
748 Err("Unknown GPU optimization".into())
749 }
750 }
751
752 async fn apply_parallelization_optimization(
754 &mut self,
755 recommendation: &OptimizationRecommendation,
756 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
757 if recommendation.recommendation.contains("worker threads") {
758 let key = "worker_threads".to_string();
759 let previous = self
760 .current_settings
761 .get(&key)
762 .unwrap_or(&"4".to_string())
763 .clone();
764 let new_value = (previous.parse::<u32>()? + 2).to_string();
765 Ok((key, previous, new_value))
766 } else {
767 Err("Unknown parallelization optimization".into())
768 }
769 }
770
771 async fn apply_caching_optimization(
773 &mut self,
774 recommendation: &OptimizationRecommendation,
775 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
776 if recommendation.description.contains("cache") {
777 let key = "cache_size_mb".to_string();
778 let previous = self
779 .current_settings
780 .get(&key)
781 .unwrap_or(&"256".to_string())
782 .clone();
783 let new_value = (previous.parse::<u32>()? * 2).to_string();
784 Ok((key, previous, new_value))
785 } else {
786 Err("Unknown caching optimization".into())
787 }
788 }
789
790 async fn apply_model_optimization(
792 &mut self,
793 recommendation: &OptimizationRecommendation,
794 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
795 if recommendation.recommendation.contains("quantized") {
796 let key = "model_precision".to_string();
797 let previous = self
798 .current_settings
799 .get(&key)
800 .unwrap_or(&"fp32".to_string())
801 .clone();
802 let new_value = "fp16".to_string();
803 Ok((key, previous, new_value))
804 } else {
805 Err("Unknown model optimization".into())
806 }
807 }
808
809 async fn apply_io_optimization(
811 &mut self,
812 recommendation: &OptimizationRecommendation,
813 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
814 if recommendation.description.contains("buffering") {
815 let key = "io_buffer_size".to_string();
816 let previous = self
817 .current_settings
818 .get(&key)
819 .unwrap_or(&"8192".to_string())
820 .clone();
821 let new_value = (previous.parse::<u32>()? * 2).to_string();
822 Ok((key, previous, new_value))
823 } else if recommendation.description.contains("async") {
824 let key = "async_io".to_string();
825 let previous = self
826 .current_settings
827 .get(&key)
828 .unwrap_or(&"false".to_string())
829 .clone();
830 let new_value = "true".to_string();
831 Ok((key, previous, new_value))
832 } else {
833 Err("Unknown I/O optimization".into())
834 }
835 }
836
837 async fn apply_network_optimization(
839 &mut self,
840 recommendation: &OptimizationRecommendation,
841 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
842 if recommendation.description.contains("compression") {
843 let key = "network_compression".to_string();
844 let previous = self
845 .current_settings
846 .get(&key)
847 .unwrap_or(&"none".to_string())
848 .clone();
849 let new_value = "gzip".to_string();
850 Ok((key, previous, new_value))
851 } else if recommendation.description.contains("connection pool") {
852 let key = "connection_pool_size".to_string();
853 let previous = self
854 .current_settings
855 .get(&key)
856 .unwrap_or(&"10".to_string())
857 .clone();
858 let new_value = (previous.parse::<u32>()? * 2).to_string();
859 Ok((key, previous, new_value))
860 } else {
861 Err("Unknown network optimization".into())
862 }
863 }
864
865 async fn apply_configuration_optimization(
867 &mut self,
868 recommendation: &OptimizationRecommendation,
869 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
870 if recommendation.description.contains("sample rate") {
871 let key = "sample_rate".to_string();
872 let previous = self
873 .current_settings
874 .get(&key)
875 .unwrap_or(&"22050".to_string())
876 .clone();
877 let new_value = "16000".to_string();
878 Ok((key, previous, new_value))
879 } else if recommendation.description.contains("quality") {
880 let key = "quality_preset".to_string();
881 let previous = self
882 .current_settings
883 .get(&key)
884 .unwrap_or(&"high".to_string())
885 .clone();
886 let new_value = "medium".to_string();
887 Ok((key, previous, new_value))
888 } else {
889 Err("Unknown configuration optimization".into())
890 }
891 }
892
893 async fn apply_resource_allocation_optimization(
895 &mut self,
896 recommendation: &OptimizationRecommendation,
897 ) -> Result<(String, String, String), Box<dyn std::error::Error>> {
898 if recommendation.description.contains("worker threads") {
899 let key = "worker_threads".to_string();
900 let previous = self
901 .current_settings
902 .get(&key)
903 .unwrap_or(&"4".to_string())
904 .clone();
905 let cpu_count = num_cpus::get();
906 let new_value = cpu_count.to_string();
907 Ok((key, previous, new_value))
908 } else if recommendation.description.contains("memory limit") {
909 let key = "memory_limit_mb".to_string();
910 let previous = self
911 .current_settings
912 .get(&key)
913 .unwrap_or(&"1024".to_string())
914 .clone();
915 let new_value = (previous.parse::<u32>()? * 2).to_string();
916 Ok((key, previous, new_value))
917 } else {
918 Err("Unknown resource allocation optimization".into())
919 }
920 }
921
922 pub fn get_optimization_history(&self) -> &[OptimizationResult] {
924 &self.optimization_history
925 }
926
927 pub fn get_current_settings(&self) -> &HashMap<String, String> {
929 &self.current_settings
930 }
931
932 pub fn update_config(&mut self, config: OptimizerConfig) {
934 self.config = config;
935 }
936}
937
938impl Default for OptimizerConfig {
939 fn default() -> Self {
940 Self {
941 auto_optimize: false,
942 min_improvement_threshold: 0.1,
943 max_optimization_attempts: 5,
944 optimization_targets: vec![
945 OptimizationTarget {
946 category: OptimizationCategory::Memory,
947 weight: 0.8,
948 auto_optimize: true,
949 },
950 OptimizationTarget {
951 category: OptimizationCategory::Cpu,
952 weight: 0.9,
953 auto_optimize: true,
954 },
955 OptimizationTarget {
956 category: OptimizationCategory::Gpu,
957 weight: 0.7,
958 auto_optimize: false,
959 },
960 ],
961 resource_constraints: ResourceConstraints::default(),
962 aggressiveness: 5,
963 }
964 }
965}
966
967impl Default for ResourceConstraints {
968 fn default() -> Self {
969 Self {
970 max_memory_mb: Some(8192),
971 max_cpu_percent: Some(80.0),
972 max_gpu_memory_mb: Some(6144),
973 min_disk_space_mb: Some(1024),
974 target_latency_ms: Some(500.0),
975 }
976 }
977}
978
979#[cfg(test)]
980mod tests {
981 use super::*;
982
983 #[test]
984 fn test_optimizer_config_default() {
985 let config = OptimizerConfig::default();
986 assert!(!config.auto_optimize);
987 assert_eq!(config.aggressiveness, 5);
988 assert!(config.optimization_targets.len() > 0);
989 }
990
991 #[tokio::test]
992 async fn test_performance_optimizer_creation() {
993 let config = OptimizerConfig::default();
994 let optimizer = PerformanceOptimizer::new(config);
995 assert_eq!(optimizer.optimization_history.len(), 0);
996 assert_eq!(optimizer.current_settings.len(), 0);
997 }
998
999 #[tokio::test]
1000 async fn test_memory_optimization_analysis() {
1001 let config = OptimizerConfig::default();
1002 let optimizer = PerformanceOptimizer::new(config);
1003
1004 let mut recommendations = Vec::new();
1005 let memory = MemoryMetrics {
1006 heap_used: 8_000_000_000, fragmentation_percent: 25.0,
1008 cache_hit_rate: 50.0,
1009 ..Default::default()
1010 };
1011 let system = SystemMetrics {
1012 memory_used: 8_000_000_000,
1013 memory_available: 2_000_000_000,
1014 ..Default::default()
1015 };
1016
1017 optimizer
1018 .analyze_memory_optimization(&mut recommendations, &memory, &system, 1.0)
1019 .await;
1020
1021 assert!(recommendations.len() > 0);
1022 assert!(recommendations
1023 .iter()
1024 .any(|r| r.category == OptimizationCategory::Memory));
1025 }
1026
1027 #[tokio::test]
1028 async fn test_cpu_optimization_analysis() {
1029 let config = OptimizerConfig::default();
1030 let optimizer = PerformanceOptimizer::new(config);
1031
1032 let mut recommendations = Vec::new();
1033 let system = SystemMetrics {
1034 cpu_usage: 95.0, ..Default::default()
1036 };
1037 let synthesis = SynthesisMetrics {
1038 real_time_factor: 0.5, ..Default::default()
1040 };
1041
1042 optimizer
1043 .analyze_cpu_optimization(&mut recommendations, &system, &synthesis, 1.0)
1044 .await;
1045
1046 assert!(recommendations.len() > 0);
1047 assert!(recommendations
1048 .iter()
1049 .any(|r| r.category == OptimizationCategory::Cpu
1050 || r.category == OptimizationCategory::ModelOptimization));
1051 }
1052
1053 #[tokio::test]
1054 async fn test_optimization_recommendation_sorting() {
1055 let config = OptimizerConfig::default();
1056 let optimizer = PerformanceOptimizer::new(config);
1057
1058 let metrics = PerformanceMetrics {
1059 system: SystemMetrics {
1060 cpu_usage: 95.0,
1061 memory_used: 8_000_000_000,
1062 memory_available: 2_000_000_000,
1063 ..Default::default()
1064 },
1065 memory: MemoryMetrics {
1066 heap_used: 8_000_000_000,
1067 cache_hit_rate: 50.0,
1068 ..Default::default()
1069 },
1070 synthesis: SynthesisMetrics {
1071 real_time_factor: 0.5,
1072 ..Default::default()
1073 },
1074 ..Default::default()
1075 };
1076
1077 let recommendations = optimizer.analyze_and_recommend(&metrics).await;
1078
1079 assert!(!recommendations.is_empty());
1080
1081 for i in 1..recommendations.len() {
1083 assert!(recommendations[i - 1].priority >= recommendations[i].priority);
1084 }
1085 }
1086}