use std::collections::{BTreeMap, HashMap};
use std::hash::Hash;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum PerformanceMetricType {
CpuUtilization,
MemoryUtilization,
GcTime,
CompilationTime,
ExecutionTime,
HeapSize,
StackSize,
ThreadCount,
JitCompilationTime,
CodeCacheHitRate,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct PerformanceMetric {
pub metric_type: PerformanceMetricType,
pub value: f64,
pub timestamp: SystemTime,
pub labels: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct PerformanceMetrics {
pub metrics: Vec<PerformanceMetric>,
pub time_range: (SystemTime, SystemTime),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum OptimizationTarget {
Latency,
Throughput,
MemoryUsage,
CpuUsage,
GcTime,
StartupTime,
JitPerformance,
CachePerformance,
Custom(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum OptimizationType {
JitOptimization,
MemoryOptimization,
GcTuning,
ThreadOptimization,
CacheOptimization,
CompilationOptimization,
InlineOptimization,
EscapeAnalysisOptimization,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct OptimizationSuggestion {
pub optimization_type: OptimizationType,
pub target: OptimizationTarget,
pub parameter: String,
pub current_value: String,
pub recommended_value: String,
pub expected_improvement: f64,
pub confidence: f64,
pub description: String,
}
#[derive(Debug, Clone)]
pub struct OptimizationPlan {
pub target: OptimizationTarget,
pub current_score: f64,
pub target_score: f64,
pub suggestions: Vec<OptimizationSuggestion>,
pub estimated_improvement: f64,
pub risk_level: f64,
}
pub struct PerformanceAnalyzer {
pub window_size: usize,
pub anomaly_threshold: f64,
}
impl PerformanceAnalyzer {
pub fn new() -> Self {
Self {
window_size: 100,
anomaly_threshold: 2.0, }
}
pub fn with_config(window_size: usize, anomaly_threshold: f64) -> Self {
Self {
window_size,
anomaly_threshold,
}
}
pub fn analyze_performance(&self, metrics: &PerformanceMetrics) -> OptimizationPlan {
if metrics.metrics.is_empty() {
return OptimizationPlan {
target: OptimizationTarget::Latency,
current_score: 0.0,
target_score: 0.0,
suggestions: Vec::new(),
estimated_improvement: 0.0,
risk_level: 0.0,
};
}
let (avg_cpu, avg_memory, avg_gc, avg_jit, avg_cache) =
self.calculate_average_metrics(metrics);
let current_score: _ =
self.calculate_performance_score(avg_cpu, avg_memory, avg_gc, avg_jit, avg_cache);
let suggestions: _ =
self.generate_optimization_suggestions(avg_cpu, avg_memory, avg_gc, avg_jit, avg_cache);
let estimated_improvement: _ = if !suggestions.is_empty() {
suggestions
.iter()
.map(|s| s.expected_improvement * s.confidence)
.sum::<f64>()
/ suggestions.len() as f64
} else {
0.0
};
let target_score: _ = current_score * (1.0 - estimated_improvement / 100.0);
let risk_level: _ = self.calculate_risk_level(&suggestions);
OptimizationPlan {
target: OptimizationTarget::Latency,
current_score,
target_score,
suggestions,
estimated_improvement,
risk_level,
}
}
fn calculate_average_metrics(&self, metrics: &PerformanceMetrics) -> (f64, f64, f64, f64, f64) {
let mut cpu_values = Vec::new();
let mut memory_values = Vec::new();
let mut gc_values = Vec::new();
let mut jit_values = Vec::new();
let mut cache_values = Vec::new();
for metric in &metrics.metrics {
match metric.metric_type {
PerformanceMetricType::CpuUtilization => cpu_values.push(metric.value),
PerformanceMetricType::MemoryUtilization => memory_values.push(metric.value),
PerformanceMetricType::GcTime => gc_values.push(metric.value),
PerformanceMetricType::JitCompilationTime => jit_values.push(metric.value),
PerformanceMetricType::CodeCacheHitRate => cache_values.push(metric.value),
_ => {}
}
}
let avg_cpu: _ = self.safe_average(&cpu_values);
let avg_memory: _ = self.safe_average(&memory_values);
let avg_gc: _ = self.safe_average(&gc_values);
let avg_jit: _ = self.safe_average(&jit_values);
let avg_cache: _ = self.safe_average(&cache_values);
(avg_cpu, avg_memory, avg_gc, avg_jit, avg_cache)
}
fn safe_average(&self, values: &[f64]) -> f64 {
if values.is_empty() {
0.0
} else {
values.iter().sum::<f64>() / values.len() as f64
}
}
fn calculate_performance_score(
&self,
avg_cpu: f64,
avg_memory: f64,
avg_gc: f64,
avg_jit: f64,
avg_cache: f64,
) -> f64 {
let cpu_score: _ = (100.0 - avg_cpu).max(0.0) / 100.0;
let memory_score: _ = (100.0 - avg_memory).max(0.0) / 100.0;
let gc_score: _ = (20.0 - avg_gc).max(0.0) / 20.0;
let jit_score: _ = (100.0 - avg_jit).max(0.0) / 100.0;
let cache_score: _ = avg_cache;
(cpu_score * 0.3
+ memory_score * 0.3
+ gc_score * 0.2
+ jit_score * 0.1
+ cache_score * 0.1)
* 100.0
}
fn generate_optimization_suggestions(
&self,
avg_cpu: f64,
avg_memory: f64,
avg_gc: f64,
avg_jit: f64,
avg_cache: f64,
) -> Vec<OptimizationSuggestion> {
let mut suggestions = Vec::new();
if avg_cpu > 70.0 {
suggestions.push(OptimizationSuggestion {
optimization_type: OptimizationType::JitOptimization,
target: OptimizationTarget::CpuUsage,
parameter: "max_wasm_inline_size".to_string(),
current_value: "1024".to_string(),
recommended_value: "2048".to_string(),
expected_improvement: 15.0 + (avg_cpu - 70.0) * 0.5,
confidence: 0.8,
description: "增加 WebAssembly 内联函数大小可以减少函数调用开销,提高 CPU 效率"
.to_string(),
});
suggestions.push(OptimizationSuggestion {
optimization_type: OptimizationType::InlineOptimization,
target: OptimizationTarget::CpuUsage,
parameter: "inline_threshold".to_string(),
current_value: "325".to_string(),
recommended_value: "500".to_string(),
expected_improvement: 10.0 + (avg_cpu - 70.0) * 0.3,
confidence: 0.75,
description: "提高内联阈值可以减少函数调用开销".to_string(),
});
}
if avg_memory > 80.0 {
suggestions.push(OptimizationSuggestion {
optimization_type: OptimizationType::MemoryOptimization,
target: OptimizationTarget::MemoryUsage,
parameter: "heap_initial_size".to_string(),
current_value: "64MB".to_string(),
recommended_value: "128MB".to_string(),
expected_improvement: 20.0 + (avg_memory - 80.0) * 0.8,
confidence: 0.9,
description: "增加堆初始大小可以减少内存重新分配和碎片".to_string(),
});
suggestions.push(OptimizationSuggestion {
optimization_type: OptimizationType::EscapeAnalysisOptimization,
target: OptimizationTarget::MemoryUsage,
parameter: "escape_analysis".to_string(),
current_value: "false".to_string(),
recommended_value: "true".to_string(),
expected_improvement: 12.0,
confidence: 0.7,
description: "启用逃逸分析可以优化对象分配".to_string(),
});
}
if avg_gc > 15.0 {
suggestions.push(OptimizationSuggestion {
optimization_type: OptimizationType::GcTuning,
target: OptimizationTarget::GcTime,
parameter: "gc_threshold".to_string(),
current_value: "1000".to_string(),
recommended_value: "2000".to_string(),
expected_improvement: 25.0 + (avg_gc - 15.0) * 1.5,
confidence: 0.85,
description: "提高 GC 阈值可以减少 GC 频率,提高吞吐量".to_string(),
});
suggestions.push(OptimizationSuggestion {
optimization_type: OptimizationType::GcTuning,
target: OptimizationTarget::GcTime,
parameter: "gc_parallel_threads".to_string(),
current_value: "2".to_string(),
recommended_value: "4".to_string(),
expected_improvement: 15.0,
confidence: 0.8,
description: "增加 GC 并行线程数可以加速垃圾回收".to_string(),
});
}
if avg_jit > 100.0 {
suggestions.push(OptimizationSuggestion {
optimization_type: OptimizationType::JitOptimization,
target: OptimizationTarget::JitPerformance,
parameter: "tiered_compilation".to_string(),
current_value: "false".to_string(),
recommended_value: "true".to_string(),
expected_improvement: 18.0,
confidence: 0.85,
description: "启用分层编译可以平衡启动速度和峰值性能".to_string(),
});
suggestions.push(OptimizationSuggestion {
optimization_type: OptimizationType::JitOptimization,
target: OptimizationTarget::JitPerformance,
parameter: "code_cache_size".to_string(),
current_value: "48MB".to_string(),
recommended_value: "64MB".to_string(),
expected_improvement: 12.0,
confidence: 0.75,
description: "增加代码缓存大小可以减少代码回收".to_string(),
});
}
if avg_cache < 0.8 {
suggestions.push(OptimizationSuggestion {
optimization_type: OptimizationType::CacheOptimization,
target: OptimizationTarget::CachePerformance,
parameter: "code_cache_size".to_string(),
current_value: "48MB".to_string(),
recommended_value: "64MB".to_string(),
expected_improvement: (0.9 - avg_cache) * 50.0,
confidence: 0.8,
description: "增加代码缓存大小可以提高缓存命中率".to_string(),
});
}
suggestions
}
fn calculate_risk_level(&self, suggestions: &[OptimizationSuggestion]) -> f64 {
if suggestions.is_empty() {
return 0.0;
}
let avg_confidence: f64 =
suggestions.iter().map(|s| s.confidence).sum::<f64>() / suggestions.len() as f64;
1.0 - avg_confidence
}
}
impl Default for PerformanceAnalyzer {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::{Duration, SystemTime};
#[test]
fn test_performance_analyzer_creation() {
let analyzer: _ = PerformanceAnalyzer::new();
assert_eq!(analyzer.window_size, 100);
assert_eq!(analyzer.anomaly_threshold, 2.0);
}
#[test]
fn test_performance_analyzer_with_config() {
let analyzer: _ = PerformanceAnalyzer::with_config(200, 3.0);
assert_eq!(analyzer.window_size, 200);
assert_eq!(analyzer.anomaly_threshold, 3.0);
}
#[test]
fn test_safe_average() {
let analyzer: _ = PerformanceAnalyzer::new();
assert_eq!(analyzer.safe_average(&[1.0, 2.0, 3.0]), 2.0);
assert_eq!(analyzer.safe_average(&[]), 0.0);
assert_eq!(analyzer.safe_average(&[5.0]), 5.0);
}
#[test]
fn test_analyze_empty_metrics() {
let analyzer: _ = PerformanceAnalyzer::new();
let empty_metrics: _ = PerformanceMetrics {
metrics: Vec::new(),
time_range: (SystemTime::now(), SystemTime::now()),
};
let plan: _ = analyzer.analyze_performance(&empty_metrics);
assert_eq!(plan.suggestions.len(), 0);
assert_eq!(plan.current_score, 0.0);
assert_eq!(plan.target_score, 0.0);
}
}