1use std::collections::HashMap;
7use std::time::{Instant, SystemTime, UNIX_EPOCH};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub enum ProcessorType {
12 QuantumInspired,
13 NeuralAdaptive,
14 QuantumNeuralHybrid,
15 MemoryCompression,
16}
17
18impl std::fmt::Display for ProcessorType {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 match self {
21 ProcessorType::QuantumInspired => write!(f, "QuantumInspired"),
22 ProcessorType::NeuralAdaptive => write!(f, "NeuralAdaptive"),
23 ProcessorType::QuantumNeuralHybrid => write!(f, "QuantumNeuralHybrid"),
24 ProcessorType::MemoryCompression => write!(f, "MemoryCompression"),
25 }
26 }
27}
28
29impl ProcessorType {
30 pub fn all() -> Vec<ProcessorType> {
32 vec![
33 ProcessorType::QuantumInspired,
34 ProcessorType::NeuralAdaptive,
35 ProcessorType::QuantumNeuralHybrid,
36 ProcessorType::MemoryCompression,
37 ]
38 }
39
40 pub fn supports_quantum_metrics(&self) -> bool {
42 matches!(
43 self,
44 ProcessorType::QuantumInspired | ProcessorType::QuantumNeuralHybrid
45 )
46 }
47
48 pub fn supports_neural_metrics(&self) -> bool {
49 matches!(
50 self,
51 ProcessorType::NeuralAdaptive | ProcessorType::QuantumNeuralHybrid
52 )
53 }
54
55 pub fn supports_compression_metrics(&self) -> bool {
56 matches!(self, ProcessorType::MemoryCompression)
57 }
58}
59
60#[derive(Debug, Clone)]
62pub struct PerformanceSample {
63 pub timestamp: u64,
64 pub processor_type: ProcessorType,
65 pub processor_id: String,
66 pub execution_time_ms: f64,
67 pub throughput_ops_per_sec: f64,
68 pub memory_usage_mb: f64,
69 pub cache_hit_ratio: f64,
70 pub error_rate: f64,
71 pub cpu_utilization: f64,
72 pub gpu_utilization: f64,
73 pub quantum_coherence: Option<f64>,
74 pub neural_confidence: Option<f64>,
75 pub compression_ratio: Option<f64>,
76 pub custom_metrics: HashMap<String, f64>,
77}
78
79impl PerformanceSample {
80 pub fn new(processor_type: ProcessorType, processor_id: String) -> Self {
82 Self {
83 timestamp: SystemTime::now()
84 .duration_since(UNIX_EPOCH)
85 .unwrap_or_default()
86 .as_millis() as u64,
87 processor_type,
88 processor_id,
89 execution_time_ms: 0.0,
90 throughput_ops_per_sec: 0.0,
91 memory_usage_mb: 0.0,
92 cache_hit_ratio: 0.0,
93 error_rate: 0.0,
94 cpu_utilization: 0.0,
95 gpu_utilization: 0.0,
96 quantum_coherence: None,
97 neural_confidence: None,
98 compression_ratio: None,
99 custom_metrics: HashMap::new(),
100 }
101 }
102
103 pub fn with_execution_time(mut self, execution_time_ms: f64) -> Self {
105 self.execution_time_ms = execution_time_ms;
106 self
107 }
108
109 pub fn with_throughput(mut self, throughput_ops_per_sec: f64) -> Self {
111 self.throughput_ops_per_sec = throughput_ops_per_sec;
112 self
113 }
114
115 pub fn with_memory_usage(mut self, memory_usage_mb: f64) -> Self {
117 self.memory_usage_mb = memory_usage_mb;
118 self
119 }
120
121 pub fn with_cache_hit_ratio(mut self, cache_hit_ratio: f64) -> Self {
123 self.cache_hit_ratio = cache_hit_ratio.clamp(0.0, 1.0);
124 self
125 }
126
127 pub fn with_error_rate(mut self, error_rate: f64) -> Self {
129 self.error_rate = error_rate.clamp(0.0, 1.0);
130 self
131 }
132
133 pub fn with_cpu_utilization(mut self, cpu_utilization: f64) -> Self {
135 self.cpu_utilization = cpu_utilization.clamp(0.0, 1.0);
136 self
137 }
138
139 pub fn with_gpu_utilization(mut self, gpu_utilization: f64) -> Self {
141 self.gpu_utilization = gpu_utilization.clamp(0.0, 1.0);
142 self
143 }
144
145 pub fn with_quantum_coherence(mut self, coherence: f64) -> Self {
147 if self.processor_type.supports_quantum_metrics() {
148 self.quantum_coherence = Some(coherence.clamp(0.0, 1.0));
149 }
150 self
151 }
152
153 pub fn with_neural_confidence(mut self, confidence: f64) -> Self {
155 if self.processor_type.supports_neural_metrics() {
156 self.neural_confidence = Some(confidence.clamp(0.0, 1.0));
157 }
158 self
159 }
160
161 pub fn with_compression_ratio(mut self, ratio: f64) -> Self {
163 if self.processor_type.supports_compression_metrics() {
164 self.compression_ratio = Some(ratio.max(0.0));
165 }
166 self
167 }
168
169 pub fn with_custom_metric(mut self, name: String, value: f64) -> Self {
171 self.custom_metrics.insert(name, value);
172 self
173 }
174
175 pub fn efficiency_score(&self) -> f64 {
177 let mut score = 0.0;
178 let mut factors = 0;
179
180 if self.throughput_ops_per_sec > 0.0 {
182 score += (self.throughput_ops_per_sec / 1000.0).min(1.0);
183 factors += 1;
184 }
185
186 if self.execution_time_ms > 0.0 {
188 score += (1.0 / (1.0 + self.execution_time_ms / 1000.0)).min(1.0);
189 factors += 1;
190 }
191
192 score += self.cache_hit_ratio;
194 factors += 1;
195
196 score += 1.0 - self.error_rate;
198 factors += 1;
199
200 let cpu_factor = if self.cpu_utilization > 0.9 {
202 0.5
203 } else {
204 self.cpu_utilization
205 };
206 let gpu_factor = if self.gpu_utilization > 0.9 {
207 0.5
208 } else {
209 self.gpu_utilization
210 };
211 score += (cpu_factor + gpu_factor) / 2.0;
212 factors += 1;
213
214 if let Some(coherence) = self.quantum_coherence {
216 score += coherence;
217 factors += 1;
218 }
219
220 if let Some(confidence) = self.neural_confidence {
221 score += confidence;
222 factors += 1;
223 }
224
225 if let Some(ratio) = self.compression_ratio {
226 score += (ratio / 10.0).min(1.0); factors += 1;
228 }
229
230 if factors > 0 {
231 score / factors as f64
232 } else {
233 0.0
234 }
235 }
236
237 pub fn has_performance_issues(&self) -> Vec<String> {
239 let mut issues = Vec::new();
240
241 if self.execution_time_ms > 1000.0 {
242 issues.push("High execution time".to_string());
243 }
244
245 if self.throughput_ops_per_sec < 10.0 {
246 issues.push("Low throughput".to_string());
247 }
248
249 if self.cache_hit_ratio < 0.5 {
250 issues.push("Low cache hit ratio".to_string());
251 }
252
253 if self.error_rate > 0.1 {
254 issues.push("High error rate".to_string());
255 }
256
257 if self.cpu_utilization > 0.95 {
258 issues.push("CPU overutilization".to_string());
259 }
260
261 if self.memory_usage_mb > 1000.0 {
262 issues.push("High memory usage".to_string());
263 }
264
265 if let Some(coherence) = self.quantum_coherence {
266 if coherence < 0.3 {
267 issues.push("Low quantum coherence".to_string());
268 }
269 }
270
271 if let Some(confidence) = self.neural_confidence {
272 if confidence < 0.5 {
273 issues.push("Low neural confidence".to_string());
274 }
275 }
276
277 issues
278 }
279
280 pub fn get_metric(&self, name: &str) -> Option<f64> {
282 match name {
283 "execution_time_ms" => Some(self.execution_time_ms),
284 "throughput_ops_per_sec" => Some(self.throughput_ops_per_sec),
285 "memory_usage_mb" => Some(self.memory_usage_mb),
286 "cache_hit_ratio" => Some(self.cache_hit_ratio),
287 "error_rate" => Some(self.error_rate),
288 "cpu_utilization" => Some(self.cpu_utilization),
289 "gpu_utilization" => Some(self.gpu_utilization),
290 "quantum_coherence" => self.quantum_coherence,
291 "neural_confidence" => self.neural_confidence,
292 "compression_ratio" => self.compression_ratio,
293 "efficiency_score" => Some(self.efficiency_score()),
294 _ => self.custom_metrics.get(name).copied(),
295 }
296 }
297
298 pub fn metric_names(&self) -> Vec<String> {
300 let mut names = vec![
301 "execution_time_ms".to_string(),
302 "throughput_ops_per_sec".to_string(),
303 "memory_usage_mb".to_string(),
304 "cache_hit_ratio".to_string(),
305 "error_rate".to_string(),
306 "cpu_utilization".to_string(),
307 "gpu_utilization".to_string(),
308 "efficiency_score".to_string(),
309 ];
310
311 if self.quantum_coherence.is_some() {
312 names.push("quantum_coherence".to_string());
313 }
314
315 if self.neural_confidence.is_some() {
316 names.push("neural_confidence".to_string());
317 }
318
319 if self.compression_ratio.is_some() {
320 names.push("compression_ratio".to_string());
321 }
322
323 names.extend(self.custom_metrics.keys().cloned());
324 names
325 }
326}
327
328#[derive(Debug, Default, Clone)]
330pub struct AggregatedMetrics {
331 pub avg_execution_time: f64,
332 pub avg_throughput: f64,
333 pub avg_memory_usage: f64,
334 pub avg_cache_hit_ratio: f64,
335 pub avg_error_rate: f64,
336 pub avg_cpu_utilization: f64,
337 pub avg_gpu_utilization: f64,
338 pub peak_throughput: f64,
339 pub min_execution_time: f64,
340 pub max_execution_time: f64,
341 pub total_operations: usize,
342 pub efficiency_score: f64,
343 pub sample_count: usize,
344}
345
346impl AggregatedMetrics {
347 pub fn new() -> Self {
349 Self {
350 min_execution_time: f64::INFINITY,
351 max_execution_time: 0.0,
352 ..Default::default()
353 }
354 }
355
356 pub fn update_with_sample(&mut self, sample: &PerformanceSample) {
358 let n = self.sample_count as f64;
359 let new_n = n + 1.0;
360
361 self.avg_execution_time = (self.avg_execution_time * n + sample.execution_time_ms) / new_n;
363 self.avg_throughput = (self.avg_throughput * n + sample.throughput_ops_per_sec) / new_n;
364 self.avg_memory_usage = (self.avg_memory_usage * n + sample.memory_usage_mb) / new_n;
365 self.avg_cache_hit_ratio = (self.avg_cache_hit_ratio * n + sample.cache_hit_ratio) / new_n;
366 self.avg_error_rate = (self.avg_error_rate * n + sample.error_rate) / new_n;
367 self.avg_cpu_utilization = (self.avg_cpu_utilization * n + sample.cpu_utilization) / new_n;
368 self.avg_gpu_utilization = (self.avg_gpu_utilization * n + sample.gpu_utilization) / new_n;
369 self.efficiency_score = (self.efficiency_score * n + sample.efficiency_score()) / new_n;
370
371 self.peak_throughput = self.peak_throughput.max(sample.throughput_ops_per_sec);
373 self.min_execution_time = self.min_execution_time.min(sample.execution_time_ms);
374 self.max_execution_time = self.max_execution_time.max(sample.execution_time_ms);
375
376 self.total_operations += 1;
377 self.sample_count += 1;
378 }
379
380 pub fn reset(&mut self) {
382 *self = Self::new();
383 }
384
385 pub fn execution_time_variance(&self, samples: &[PerformanceSample]) -> f64 {
387 if samples.len() <= 1 {
388 return 0.0;
389 }
390
391 let mean = self.avg_execution_time;
392 let variance = samples
393 .iter()
394 .map(|s| (s.execution_time_ms - mean).powi(2))
395 .sum::<f64>()
396 / (samples.len() - 1) as f64;
397
398 variance
399 }
400
401 pub fn stability_score(&self, samples: &[PerformanceSample]) -> f64 {
403 if samples.is_empty() {
404 return 0.0;
405 }
406
407 let variance = self.execution_time_variance(samples);
408 let coefficient_of_variation = if self.avg_execution_time > 0.0 {
409 variance.sqrt() / self.avg_execution_time
410 } else {
411 0.0
412 };
413
414 (1.0 / (1.0 + coefficient_of_variation)).clamp(0.0, 1.0)
416 }
417}
418
419#[derive(Debug, Clone)]
421pub struct SystemMetrics {
422 pub cpu_usage: f64,
423 pub memory_usage: f64,
424 pub gpu_usage: f64,
425 pub network_io: f64,
426 pub disk_io: f64,
427 pub temperature: f64,
428 pub power_consumption: f64,
429 pub system_load: f64,
430 pub available_memory_mb: f64,
431 pub cpu_frequency_mhz: f64,
432 pub timestamp: u64,
433}
434
435impl SystemMetrics {
436 pub fn new() -> Self {
438 Self {
439 cpu_usage: 0.0,
440 memory_usage: 0.0,
441 gpu_usage: 0.0,
442 network_io: 0.0,
443 disk_io: 0.0,
444 temperature: 0.0,
445 power_consumption: 0.0,
446 system_load: 0.0,
447 available_memory_mb: 0.0,
448 cpu_frequency_mhz: 0.0,
449 timestamp: SystemTime::now()
450 .duration_since(UNIX_EPOCH)
451 .unwrap_or_default()
452 .as_millis() as u64,
453 }
454 }
455
456 pub fn update_timestamp(&mut self) {
458 self.timestamp = SystemTime::now()
459 .duration_since(UNIX_EPOCH)
460 .unwrap_or_default()
461 .as_millis() as u64;
462 }
463
464 pub fn is_high_load(&self) -> bool {
466 self.cpu_usage > 0.8 || self.memory_usage > 0.9 || self.system_load > 2.0
467 }
468
469 pub fn health_score(&self) -> f64 {
471 let mut score = 0.0;
472 let mut factors = 0;
473
474 let cpu_score = if self.cpu_usage > 0.9 {
476 0.2
477 } else if self.cpu_usage > 0.8 {
478 0.8
479 } else if self.cpu_usage > 0.6 {
480 1.0
481 } else {
482 self.cpu_usage / 0.6
483 };
484 score += cpu_score;
485 factors += 1;
486
487 score += 1.0 - self.memory_usage;
489 factors += 1;
490
491 if self.temperature > 0.0 {
493 let temp_score = if self.temperature > 80.0 {
494 0.0
495 } else if self.temperature > 70.0 {
496 (80.0 - self.temperature) / 10.0
497 } else {
498 1.0
499 };
500 score += temp_score;
501 factors += 1;
502 }
503
504 let load_score = (1.0 / (1.0 + self.system_load)).clamp(0.0, 1.0);
506 score += load_score;
507 factors += 1;
508
509 if factors > 0 {
510 score / factors as f64
511 } else {
512 0.0
513 }
514 }
515}
516
517impl Default for SystemMetrics {
518 fn default() -> Self {
519 Self::new()
520 }
521}
522
523#[derive(Debug)]
525pub struct ExecutionTimer {
526 start_time: Instant,
527 label: Option<String>,
528}
529
530impl ExecutionTimer {
531 pub fn new() -> Self {
533 Self {
534 start_time: Instant::now(),
535 label: None,
536 }
537 }
538
539 pub fn with_label(label: String) -> Self {
541 Self {
542 start_time: Instant::now(),
543 label: Some(label),
544 }
545 }
546
547 pub fn elapsed_ms(&self) -> f64 {
549 self.start_time.elapsed().as_millis() as f64
550 }
551
552 pub fn elapsed_us(&self) -> f64 {
554 self.start_time.elapsed().as_micros() as f64
555 }
556
557 pub fn elapsed_ns(&self) -> u64 {
559 self.start_time.elapsed().as_nanos() as u64
560 }
561
562 pub fn restart(&mut self) {
564 self.start_time = Instant::now();
565 }
566
567 pub fn label(&self) -> Option<&str> {
569 self.label.as_deref()
570 }
571
572 pub fn set_label(&mut self, label: String) {
574 self.label = Some(label);
575 }
576
577 pub fn to_sample(
579 &self,
580 processor_type: ProcessorType,
581 processor_id: String,
582 ) -> PerformanceSample {
583 PerformanceSample::new(processor_type, processor_id).with_execution_time(self.elapsed_ms())
584 }
585}
586
587impl Default for ExecutionTimer {
588 fn default() -> Self {
589 Self::new()
590 }
591}
592
593#[cfg(test)]
594mod tests {
595 use super::*;
596
597 #[test]
598 fn test_processor_type_display() {
599 assert_eq!(
600 ProcessorType::QuantumInspired.to_string(),
601 "QuantumInspired"
602 );
603 assert_eq!(ProcessorType::NeuralAdaptive.to_string(), "NeuralAdaptive");
604 assert_eq!(
605 ProcessorType::QuantumNeuralHybrid.to_string(),
606 "QuantumNeuralHybrid"
607 );
608 assert_eq!(
609 ProcessorType::MemoryCompression.to_string(),
610 "MemoryCompression"
611 );
612 }
613
614 #[test]
615 fn test_processor_type_capabilities() {
616 assert!(ProcessorType::QuantumInspired.supports_quantum_metrics());
617 assert!(!ProcessorType::QuantumInspired.supports_neural_metrics());
618 assert!(!ProcessorType::QuantumInspired.supports_compression_metrics());
619
620 assert!(!ProcessorType::NeuralAdaptive.supports_quantum_metrics());
621 assert!(ProcessorType::NeuralAdaptive.supports_neural_metrics());
622 assert!(!ProcessorType::NeuralAdaptive.supports_compression_metrics());
623
624 assert!(ProcessorType::QuantumNeuralHybrid.supports_quantum_metrics());
625 assert!(ProcessorType::QuantumNeuralHybrid.supports_neural_metrics());
626 assert!(!ProcessorType::QuantumNeuralHybrid.supports_compression_metrics());
627
628 assert!(!ProcessorType::MemoryCompression.supports_quantum_metrics());
629 assert!(!ProcessorType::MemoryCompression.supports_neural_metrics());
630 assert!(ProcessorType::MemoryCompression.supports_compression_metrics());
631 }
632
633 #[test]
634 fn test_performance_sample_creation() {
635 let sample =
636 PerformanceSample::new(ProcessorType::QuantumInspired, "test-processor".to_string());
637
638 assert_eq!(sample.processor_type, ProcessorType::QuantumInspired);
639 assert_eq!(sample.processor_id, "test-processor");
640 assert_eq!(sample.execution_time_ms, 0.0);
641 assert!(sample.timestamp > 0);
642 }
643
644 #[test]
645 fn test_performance_sample_builder() {
646 let sample = PerformanceSample::new(ProcessorType::NeuralAdaptive, "test".to_string())
647 .with_execution_time(100.0)
648 .with_throughput(500.0)
649 .with_cache_hit_ratio(0.8)
650 .with_neural_confidence(0.9);
651
652 assert_eq!(sample.execution_time_ms, 100.0);
653 assert_eq!(sample.throughput_ops_per_sec, 500.0);
654 assert_eq!(sample.cache_hit_ratio, 0.8);
655 assert_eq!(sample.neural_confidence, Some(0.9));
656 }
657
658 #[test]
659 fn test_efficiency_score_calculation() {
660 let sample = PerformanceSample::new(ProcessorType::QuantumInspired, "test".to_string())
661 .with_execution_time(100.0)
662 .with_throughput(1000.0)
663 .with_cache_hit_ratio(0.9)
664 .with_error_rate(0.1)
665 .with_cpu_utilization(0.7)
666 .with_gpu_utilization(0.6);
667
668 let score = sample.efficiency_score();
669 assert!(score > 0.0 && score <= 1.0);
670 }
671
672 #[test]
673 fn test_performance_issues_detection() {
674 let problematic_sample = PerformanceSample::new(
675 ProcessorType::QuantumInspired,
676 "test".to_string(),
677 )
678 .with_execution_time(2000.0) .with_throughput(5.0) .with_cache_hit_ratio(0.3) .with_error_rate(0.2); let issues = problematic_sample.has_performance_issues();
684 assert!(!issues.is_empty());
685 assert!(issues.contains(&"High execution time".to_string()));
686 assert!(issues.contains(&"Low throughput".to_string()));
687 assert!(issues.contains(&"Low cache hit ratio".to_string()));
688 assert!(issues.contains(&"High error rate".to_string()));
689 }
690
691 #[test]
692 fn test_aggregated_metrics_update() {
693 let mut metrics = AggregatedMetrics::new();
694
695 let sample1 = PerformanceSample::new(ProcessorType::QuantumInspired, "test".to_string())
696 .with_execution_time(100.0)
697 .with_throughput(500.0);
698
699 let sample2 = PerformanceSample::new(ProcessorType::QuantumInspired, "test".to_string())
700 .with_execution_time(200.0)
701 .with_throughput(400.0);
702
703 metrics.update_with_sample(&sample1);
704 metrics.update_with_sample(&sample2);
705
706 assert_eq!(metrics.sample_count, 2);
707 assert_eq!(metrics.avg_execution_time, 150.0);
708 assert_eq!(metrics.avg_throughput, 450.0);
709 assert_eq!(metrics.peak_throughput, 500.0);
710 assert_eq!(metrics.min_execution_time, 100.0);
711 assert_eq!(metrics.max_execution_time, 200.0);
712 }
713
714 #[test]
715 fn test_system_metrics() {
716 let mut metrics = SystemMetrics::new();
717 assert_eq!(metrics.cpu_usage, 0.0);
718 assert!(metrics.timestamp > 0);
719
720 metrics.cpu_usage = 0.5;
721 metrics.memory_usage = 0.3;
722 metrics.temperature = 65.0;
723 metrics.system_load = 1.0;
724
725 assert!(!metrics.is_high_load());
726
727 let health = metrics.health_score();
728 assert!(health > 0.0 && health <= 1.0);
729 }
730
731 #[test]
732 fn test_execution_timer() {
733 let timer = ExecutionTimer::new();
734 std::thread::sleep(std::time::Duration::from_millis(10));
735
736 let elapsed = timer.elapsed_ms();
737 assert!(elapsed >= 10.0);
738
739 let sample = timer.to_sample(ProcessorType::QuantumInspired, "test".to_string());
740 assert!(sample.execution_time_ms >= 10.0);
741 }
742
743 #[test]
744 fn test_execution_timer_with_label() {
745 let mut timer = ExecutionTimer::with_label("test-operation".to_string());
746 assert_eq!(timer.label(), Some("test-operation"));
747
748 timer.set_label("new-operation".to_string());
749 assert_eq!(timer.label(), Some("new-operation"));
750 }
751
752 #[test]
753 fn test_metric_access() {
754 let sample = PerformanceSample::new(ProcessorType::QuantumInspired, "test".to_string())
755 .with_execution_time(100.0)
756 .with_custom_metric("custom_value".to_string(), 42.0);
757
758 assert_eq!(sample.get_metric("execution_time_ms"), Some(100.0));
759 assert_eq!(sample.get_metric("custom_value"), Some(42.0));
760 assert_eq!(sample.get_metric("nonexistent"), None);
761
762 let names = sample.metric_names();
763 assert!(names.contains(&"execution_time_ms".to_string()));
764 assert!(names.contains(&"custom_value".to_string()));
765 }
766}