1use anyhow::Result;
4use regex::Regex;
5use serde::Serialize;
6use serde_json::Value;
7use std::collections::HashMap;
8
9#[derive(Debug, Clone)]
11pub struct PerformanceIssue {
12 pub issue_type: String,
13 pub severity: String,
14 pub description: String,
15 pub location: Option<String>,
16 pub recommendation: String,
17 pub complexity_estimate: Option<String>,
18 pub impact_score: Option<f64>,
19 pub optimization_effort: Option<String>,
20}
21
22#[derive(Debug, Clone, Serialize)]
24pub struct RecursiveComplexity {
25 pub function_name: String,
26 pub depth_estimate: String,
27 pub complexity: String,
28 pub optimization_potential: String,
29}
30
31#[derive(Debug, Clone, Serialize)]
33pub struct MemoryPattern {
34 pub pattern_type: String,
35 pub allocation_frequency: String,
36 pub impact: String,
37 pub recommendation: String,
38}
39
40pub struct PerformanceAnalyzer {
42 patterns: HashMap<String, Vec<PerformancePattern>>,
43 language_specific_patterns: HashMap<String, Vec<PerformancePattern>>,
44}
45
46#[derive(Debug, Clone)]
47struct PerformancePattern {
48 name: String,
49 pattern: Regex,
50 severity: String,
51 description: String,
52 recommendation: String,
53 complexity: String,
54 impact_score: f64,
55 optimization_effort: String,
56}
57
58impl PerformanceAnalyzer {
59 pub fn new() -> Self {
60 let mut analyzer = Self {
61 patterns: HashMap::new(),
62 language_specific_patterns: HashMap::new(),
63 };
64 analyzer.initialize_patterns();
65 analyzer.initialize_language_specific_patterns();
66 analyzer
67 }
68
69 fn initialize_patterns(&mut self) {
70 let time_patterns = vec![
72 PerformancePattern {
73 name: "Quadruple Nested Loop".to_string(),
74 pattern: Regex::new(r"(?s)for\s+.*?for\s+.*?for\s+.*?for\s+").unwrap(),
75 severity: "critical".to_string(),
76 description: "Quadruple nested loop detected - O(n⁴) complexity".to_string(),
77 recommendation: "Critical: Consider algorithmic redesign, data preprocessing, or caching strategies".to_string(),
78 complexity: "O(n⁴)".to_string(),
79 impact_score: 10.0,
80 optimization_effort: "High".to_string(),
81 },
82 PerformancePattern {
83 name: "Triple Nested Loop".to_string(),
84 pattern: Regex::new(r"(?s)for\s+.*?for\s+.*?for\s+").unwrap(),
85 severity: "critical".to_string(),
86 description: "Triple nested loop detected - O(n³) complexity".to_string(),
87 recommendation: "Consider algorithmic optimization, matrix operations, or divide-and-conquer approaches".to_string(),
88 complexity: "O(n³)".to_string(),
89 impact_score: 8.5,
90 optimization_effort: "High".to_string(),
91 },
92 PerformancePattern {
93 name: "Double Nested Loop".to_string(),
94 pattern: Regex::new(r"(?s)for\s+.*?for\s+").unwrap(),
95 severity: "high".to_string(),
96 description: "Double nested loop detected - O(n²) complexity".to_string(),
97 recommendation: "Consider if this can be optimized to O(n log n) using sorting or O(n) using hash tables".to_string(),
98 complexity: "O(n²)".to_string(),
99 impact_score: 6.0,
100 optimization_effort: "Medium".to_string(),
101 },
102 PerformancePattern {
103 name: "Exponential Recursion".to_string(),
104 pattern: Regex::new(r"(?s)(def|function)\s+\w+.*?(\w+\([^)]*\)\s*\+\s*\w+\([^)]*\))").unwrap(),
105 severity: "critical".to_string(),
106 description: "Potential exponential recursion pattern - O(2^n) complexity".to_string(),
107 recommendation: "Implement memoization, dynamic programming, or iterative solution".to_string(),
108 complexity: "O(2^n)".to_string(),
109 impact_score: 10.0,
110 optimization_effort: "High".to_string(),
111 },
112 PerformancePattern {
113 name: "Factorial Complexity".to_string(),
114 pattern: Regex::new(r"(?i)(factorial|permutation|all.*combinations)").unwrap(),
115 severity: "critical".to_string(),
116 description: "Potential factorial complexity detected - O(n!) complexity".to_string(),
117 recommendation: "Use pruning, branch-and-bound, or approximation algorithms".to_string(),
118 complexity: "O(n!)".to_string(),
119 impact_score: 10.0,
120 optimization_effort: "Very High".to_string(),
121 },
122 PerformancePattern {
123 name: "Inefficient String Concatenation".to_string(),
124 pattern: Regex::new(r"(?s)for\s+.*?[\+=]\s*(str|string|\w+)").unwrap(),
125 severity: "high".to_string(),
126 description: "String concatenation in loop - O(n²) complexity due to immutable strings".to_string(),
127 recommendation: "Use StringBuilder, StringBuffer, list.join(), or similar efficient methods".to_string(),
128 complexity: "O(n²)".to_string(),
129 impact_score: 5.0,
130 optimization_effort: "Low".to_string(),
131 },
132 PerformancePattern {
133 name: "Inefficient Collection Search".to_string(),
134 pattern: Regex::new(r"(?s)for\s+.*?(list|array)\.contains\s*\(").unwrap(),
135 severity: "medium".to_string(),
136 description: "Linear search in loop creates O(n²) complexity".to_string(),
137 recommendation: "Convert to Set or HashMap for O(1) lookups, reducing to O(n) overall".to_string(),
138 complexity: "O(n²)".to_string(),
139 impact_score: 4.0,
140 optimization_effort: "Low".to_string(),
141 },
142 ];
143 self.patterns
144 .insert("time_complexity".to_string(), time_patterns);
145
146 let memory_patterns = vec![
148 PerformancePattern {
149 name: "Large Object Creation in Loop".to_string(),
150 pattern: Regex::new(r"(?s)for\s+.*?new\s+\w+\s*\(").unwrap(),
151 severity: "high".to_string(),
152 description:
153 "Frequent large object allocation causing GC pressure and memory fragmentation"
154 .to_string(),
155 recommendation:
156 "Use object pooling, factory patterns, or move allocation outside loop"
157 .to_string(),
158 complexity: "O(n)".to_string(),
159 impact_score: 6.0,
160 optimization_effort: "Medium".to_string(),
161 },
162 PerformancePattern {
163 name: "Memory Leak Pattern".to_string(),
164 pattern: Regex::new(r"(?i)(global|static)\s+\w+\s*=\s*\[\]").unwrap(),
165 severity: "critical".to_string(),
166 description: "Global/static collection may grow indefinitely causing memory leaks"
167 .to_string(),
168 recommendation:
169 "Implement proper cleanup, use bounded collections, or WeakReference patterns"
170 .to_string(),
171 complexity: "O(n)".to_string(),
172 impact_score: 9.0,
173 optimization_effort: "Medium".to_string(),
174 },
175 PerformancePattern {
176 name: "Excessive Buffer Allocation".to_string(),
177 pattern: Regex::new(
178 r"(?i)(buffer|byte\[\]|char\[\])\s*=\s*new\s+.*?\[\s*\d{4,}\s*\]",
179 )
180 .unwrap(),
181 severity: "medium".to_string(),
182 description: "Large buffer allocation may cause memory pressure".to_string(),
183 recommendation:
184 "Use streaming, chunked processing, or memory-mapped files for large data"
185 .to_string(),
186 complexity: "O(1)".to_string(),
187 impact_score: 4.0,
188 optimization_effort: "Medium".to_string(),
189 },
190 PerformancePattern {
191 name: "String Interning Issues".to_string(),
192 pattern: Regex::new(r"(?s)for\s+.*?new\s+String\s*\(").unwrap(),
193 severity: "medium".to_string(),
194 description: "Excessive string object creation in loop".to_string(),
195 recommendation: "Use string interning, StringBuilder, or string constants"
196 .to_string(),
197 complexity: "O(n)".to_string(),
198 impact_score: 3.0,
199 optimization_effort: "Low".to_string(),
200 },
201 ];
202 self.patterns
203 .insert("memory_usage".to_string(), memory_patterns);
204
205 let hotspot_patterns = vec![
207 PerformancePattern {
208 name: "Database Query in Loop".to_string(),
209 pattern: Regex::new(r"(?s)for\s+.*?(query|execute|select|insert|update|delete)\s*\(").unwrap(),
210 severity: "critical".to_string(),
211 description: "Database query inside loop - classic N+1 query problem".to_string(),
212 recommendation: "Use batch operations, joins, or implement query result caching".to_string(),
213 complexity: "O(n)".to_string(),
214 impact_score: 9.0,
215 optimization_effort: "Medium".to_string(),
216 },
217 PerformancePattern {
218 name: "File I/O in Loop".to_string(),
219 pattern: Regex::new(r"(?s)for\s+.*?(open|read|write|close|file)\s*\(").unwrap(),
220 severity: "high".to_string(),
221 description: "File I/O operations inside loop causing excessive disk access".to_string(),
222 recommendation: "Batch file operations, use streaming, or implement file caching".to_string(),
223 complexity: "O(n)".to_string(),
224 impact_score: 7.0,
225 optimization_effort: "Medium".to_string(),
226 },
227 PerformancePattern {
228 name: "Network Call in Loop".to_string(),
229 pattern: Regex::new(r"(?s)for\s+.*?(http|fetch|request|get|post|ajax)\s*\(").unwrap(),
230 severity: "critical".to_string(),
231 description: "Network calls inside loop causing severe latency issues".to_string(),
232 recommendation: "Use batch APIs, parallel processing with connection pooling, or async/await patterns".to_string(),
233 complexity: "O(n)".to_string(),
234 impact_score: 9.5,
235 optimization_effort: "High".to_string(),
236 },
237 PerformancePattern {
238 name: "Synchronous I/O Blocking".to_string(),
239 pattern: Regex::new(r"(?i)(sync|synchronous|blocking)\s*(read|write|call|request)").unwrap(),
240 severity: "high".to_string(),
241 description: "Synchronous I/O operations blocking thread execution".to_string(),
242 recommendation: "Implement async/await patterns, non-blocking I/O, or worker thread pools".to_string(),
243 complexity: "O(1)".to_string(),
244 impact_score: 6.0,
245 optimization_effort: "High".to_string(),
246 },
247 ];
248 self.patterns
249 .insert("hot_spots".to_string(), hotspot_patterns);
250
251 let concurrency_patterns = vec![
253 PerformancePattern {
254 name: "Thread Contention".to_string(),
255 pattern: Regex::new(r"(?i)(synchronized|lock|mutex|semaphore)\s*\([^)]*\)\s*\{[^}]*for").unwrap(),
256 severity: "high".to_string(),
257 description: "Lock contention in loop causing thread blocking and reduced parallelism".to_string(),
258 recommendation: "Use lock-free algorithms, reduce critical section size, or implement fine-grained locking".to_string(),
259 complexity: "O(n)".to_string(),
260 impact_score: 7.0,
261 optimization_effort: "High".to_string(),
262 },
263 PerformancePattern {
264 name: "False Sharing".to_string(),
265 pattern: Regex::new(r"(?i)(shared|volatile)\s+\w+\s*\[\s*\]").unwrap(),
266 severity: "medium".to_string(),
267 description: "Potential false sharing causing cache line invalidation".to_string(),
268 recommendation: "Use cache line padding, thread-local storage, or redesign data structures".to_string(),
269 complexity: "O(1)".to_string(),
270 impact_score: 5.0,
271 optimization_effort: "High".to_string(),
272 },
273 PerformancePattern {
274 name: "Thread Pool Exhaustion".to_string(),
275 pattern: Regex::new(r"(?i)thread\s*\.\s*start\s*\(\)").unwrap(),
276 severity: "medium".to_string(),
277 description: "Manual thread creation may lead to thread exhaustion".to_string(),
278 recommendation: "Use managed thread pools, async/await, or reactive patterns".to_string(),
279 complexity: "O(n)".to_string(),
280 impact_score: 4.0,
281 optimization_effort: "Medium".to_string(),
282 },
283 ];
284 self.patterns
285 .insert("concurrency_bottlenecks".to_string(), concurrency_patterns);
286
287 let algorithm_patterns = vec![
289 PerformancePattern {
290 name: "Inefficient Sorting".to_string(),
291 pattern: Regex::new(r"(?s)for\s+.*?for\s+.*?(swap|exchange|compare)").unwrap(),
292 severity: "medium".to_string(),
293 description: "Bubble sort or similar O(n²) sorting algorithm detected".to_string(),
294 recommendation:
295 "Use built-in sort functions, quicksort, mergesort, or heapsort for O(n log n)"
296 .to_string(),
297 complexity: "O(n²)".to_string(),
298 impact_score: 5.0,
299 optimization_effort: "Low".to_string(),
300 },
301 PerformancePattern {
302 name: "Linear Search in Sorted Data".to_string(),
303 pattern: Regex::new(r"(?s)for\s+.*?(sorted|ordered).*?==").unwrap(),
304 severity: "medium".to_string(),
305 description: "Linear search in sorted data structure".to_string(),
306 recommendation: "Use binary search for O(log n) complexity instead of O(n)"
307 .to_string(),
308 complexity: "O(n)".to_string(),
309 impact_score: 4.0,
310 optimization_effort: "Low".to_string(),
311 },
312 ];
313 self.patterns
314 .insert("algorithm_patterns".to_string(), algorithm_patterns);
315
316 let regression_patterns = vec![
318 PerformancePattern {
319 name: "Caching Disabled".to_string(),
320 pattern: Regex::new(r"(?i)(cache\s*=\s*false|no.?cache|disable.*cache)").unwrap(),
321 severity: "medium".to_string(),
322 description: "Caching appears to be disabled or bypassed".to_string(),
323 recommendation: "Review caching strategy and ensure proper cache utilization"
324 .to_string(),
325 complexity: "O(1)".to_string(),
326 impact_score: 6.0,
327 optimization_effort: "Low".to_string(),
328 },
329 PerformancePattern {
330 name: "Debug Code in Production".to_string(),
331 pattern: Regex::new(r"(?i)(debug|trace|verbose)\s*(=\s*true|logging|print)")
332 .unwrap(),
333 severity: "low".to_string(),
334 description: "Debug code may impact production performance".to_string(),
335 recommendation:
336 "Remove debug statements or use conditional compilation for production builds"
337 .to_string(),
338 complexity: "O(1)".to_string(),
339 impact_score: 2.0,
340 optimization_effort: "Low".to_string(),
341 },
342 ];
343 self.patterns
344 .insert("regression_patterns".to_string(), regression_patterns);
345 }
346
347 fn initialize_language_specific_patterns(&mut self) {
348 let python_patterns = vec![
350 PerformancePattern {
351 name: "Global Interpreter Lock Contention".to_string(),
352 pattern: Regex::new(r"(?i)threading.*for\s+.*?in").unwrap(),
353 severity: "high".to_string(),
354 description: "Threading in CPU-bound loop affected by Python GIL".to_string(),
355 recommendation:
356 "Use multiprocessing, asyncio, or consider Cython/PyPy for CPU-bound tasks"
357 .to_string(),
358 complexity: "O(n)".to_string(),
359 impact_score: 7.0,
360 optimization_effort: "High".to_string(),
361 },
362 PerformancePattern {
363 name: "List Comprehension Opportunity".to_string(),
364 pattern: Regex::new(r"(?s)for\s+\w+\s+in\s+.*?\.append\s*\(").unwrap(),
365 severity: "low".to_string(),
366 description: "Loop with append can be replaced with list comprehension".to_string(),
367 recommendation: "Use list comprehension for better performance and readability"
368 .to_string(),
369 complexity: "O(n)".to_string(),
370 impact_score: 2.0,
371 optimization_effort: "Low".to_string(),
372 },
373 ];
374 self.language_specific_patterns
375 .insert("python".to_string(), python_patterns);
376
377 let js_patterns = vec![
379 PerformancePattern {
380 name: "DOM Manipulation in Loop".to_string(),
381 pattern: Regex::new(
382 r"(?s)for\s+.*?(appendChild|removeChild|innerHTML|createElement)",
383 )
384 .unwrap(),
385 severity: "high".to_string(),
386 description: "DOM manipulation inside loop causing layout thrashing".to_string(),
387 recommendation: "Batch DOM changes using DocumentFragment or virtual DOM patterns"
388 .to_string(),
389 complexity: "O(n)".to_string(),
390 impact_score: 8.0,
391 optimization_effort: "Medium".to_string(),
392 },
393 PerformancePattern {
394 name: "Prototype Chain Lookup".to_string(),
395 pattern: Regex::new(r"(?s)for\s+.*?hasOwnProperty").unwrap(),
396 severity: "low".to_string(),
397 description: "Prototype chain traversal in loop".to_string(),
398 recommendation: "Cache property lookups or use Map/Set for better performance"
399 .to_string(),
400 complexity: "O(n)".to_string(),
401 impact_score: 2.0,
402 optimization_effort: "Low".to_string(),
403 },
404 ];
405 self.language_specific_patterns
406 .insert("javascript".to_string(), js_patterns);
407
408 let java_patterns = vec![
410 PerformancePattern {
411 name: "String Concatenation in Loop".to_string(),
412 pattern: Regex::new(r"(?s)for\s+.*?String\s+.*?\+\s*").unwrap(),
413 severity: "high".to_string(),
414 description: "String concatenation in loop creating many intermediate objects"
415 .to_string(),
416 recommendation: "Use StringBuilder or StringBuffer for efficient string building"
417 .to_string(),
418 complexity: "O(n²)".to_string(),
419 impact_score: 6.0,
420 optimization_effort: "Low".to_string(),
421 },
422 PerformancePattern {
423 name: "Boxing in Loop".to_string(),
424 pattern: Regex::new(r"(?s)for\s+.*?(Integer|Double|Boolean|Float)\s*\(").unwrap(),
425 severity: "medium".to_string(),
426 description: "Autoboxing/unboxing in loop creating wrapper objects".to_string(),
427 recommendation: "Use primitive collections or avoid autoboxing in hot code paths"
428 .to_string(),
429 complexity: "O(n)".to_string(),
430 impact_score: 4.0,
431 optimization_effort: "Medium".to_string(),
432 },
433 ];
434 self.language_specific_patterns
435 .insert("java".to_string(), java_patterns);
436 }
437
438 pub fn analyze_content(
440 &self,
441 content: &str,
442 analysis_types: &[String],
443 complexity_threshold: &str,
444 ) -> Result<Vec<PerformanceIssue>> {
445 let mut issues = Vec::new();
446
447 let target_types = if analysis_types.contains(&"all".to_string()) {
448 self.patterns.keys().cloned().collect::<Vec<_>>()
449 } else {
450 analysis_types.to_vec()
451 };
452
453 for analysis_type in target_types {
454 if let Some(patterns) = self.patterns.get(&analysis_type) {
455 for pattern in patterns {
456 if self.meets_complexity_threshold(&pattern.complexity, complexity_threshold) {
457 for mat in pattern.pattern.find_iter(content) {
459 issues.push(PerformanceIssue {
460 issue_type: pattern.name.clone(),
461 severity: pattern.severity.clone(),
462 description: pattern.description.clone(),
463 location: Some(self.get_line_info(content, mat.start())),
464 recommendation: pattern.recommendation.clone(),
465 complexity_estimate: Some(pattern.complexity.clone()),
466 impact_score: Some(pattern.impact_score),
467 optimization_effort: Some(pattern.optimization_effort.clone()),
468 });
469 }
470 }
471 }
472 }
473 }
474
475 Ok(issues)
476 }
477
478 pub fn analyze_recursive_complexity(&self, content: &str) -> Result<Vec<RecursiveComplexity>> {
480 let mut recursive_functions = Vec::new();
481
482 let recursive_pattern = Regex::new(r"(?s)(def|function)\s+(\w+)").unwrap();
484
485 for captures in recursive_pattern.captures_iter(content) {
486 if let Some(func_name) = captures.get(2) {
487 let function_name = func_name.as_str().to_string();
488
489 if content.contains(&format!("{}(", function_name)) {
491 let call_count = content.matches(&format!("{}(", function_name)).count();
493 if call_count > 1 {
494 let (depth_estimate, complexity, optimization_potential) =
497 self.estimate_recursive_complexity(content, &function_name);
498
499 recursive_functions.push(RecursiveComplexity {
500 function_name,
501 depth_estimate,
502 complexity,
503 optimization_potential,
504 });
505 }
506 }
507 }
508 }
509
510 Ok(recursive_functions)
511 }
512
513 pub fn analyze_memory_patterns(&self, content: &str) -> Result<Vec<MemoryPattern>> {
515 let mut patterns = Vec::new();
516
517 let allocation_patterns = vec![
519 (
520 r"(?s)for\s+.*?new\s+",
521 "Loop Allocation",
522 "High",
523 "High GC pressure",
524 ),
525 (
526 r"(?s)new\s+.*?\[\s*\d{4,}\s*\]",
527 "Large Array",
528 "Medium",
529 "Memory fragmentation",
530 ),
531 (
532 r"(?i)(arraylist|vector|list)\s*\(\s*\)",
533 "Default Capacity",
534 "Low",
535 "Potential resizing overhead",
536 ),
537 ];
538
539 for (pattern_str, pattern_type, frequency, impact) in allocation_patterns {
540 let pattern = Regex::new(pattern_str).unwrap();
541 if pattern.is_match(content) {
542 patterns.push(MemoryPattern {
543 pattern_type: pattern_type.to_string(),
544 allocation_frequency: frequency.to_string(),
545 impact: impact.to_string(),
546 recommendation: self.get_memory_recommendation(pattern_type),
547 });
548 }
549 }
550
551 Ok(patterns)
552 }
553
554 pub fn get_architectural_recommendations(&self, issues: &[PerformanceIssue]) -> Vec<String> {
556 let mut recommendations = Vec::new();
557
558 let _total_impact: f64 = issues.iter().filter_map(|i| i.impact_score).sum();
559
560 let critical_issues: usize = issues.iter().filter(|i| i.severity == "critical").count();
561
562 let high_issues: usize = issues.iter().filter(|i| i.severity == "high").count();
563
564 if critical_issues > 0 {
566 recommendations.push("CRITICAL: Immediate architectural review required".to_string());
567 recommendations
568 .push("Consider implementing performance monitoring and alerting".to_string());
569 }
570
571 if _total_impact > 30.0 {
572 recommendations.push(
573 "High performance impact detected - consider performance testing".to_string(),
574 );
575 }
576
577 if high_issues > 3 {
578 recommendations.push(
579 "Multiple high-impact issues - implement staged optimization approach".to_string(),
580 );
581 }
582
583 if issues.iter().any(|i| i.issue_type.contains("Database")) {
585 recommendations.push("Database Architecture: Implement connection pooling, read replicas, and query optimization".to_string());
586 }
587
588 if issues.iter().any(|i| i.issue_type.contains("Network")) {
589 recommendations.push(
590 "Network Architecture: Consider CDN, caching layers, and circuit breaker patterns"
591 .to_string(),
592 );
593 }
594
595 if issues.iter().any(|i| i.issue_type.contains("Memory")) {
596 recommendations.push("Memory Architecture: Implement memory profiling, garbage collection tuning, and memory-efficient data structures".to_string());
597 }
598
599 if issues
600 .iter()
601 .any(|i| i.issue_type.contains("Concurrency") || i.issue_type.contains("Thread"))
602 {
603 recommendations.push("Concurrency Architecture: Consider actor model, reactive streams, or lock-free algorithms".to_string());
604 }
605
606 recommendations.push(
607 "Implement comprehensive performance benchmarking and continuous monitoring"
608 .to_string(),
609 );
610
611 recommendations
612 }
613
614 fn estimate_recursive_complexity(
615 &self,
616 _content: &str,
617 function_name: &str,
618 ) -> (String, String, String) {
619 if function_name.contains("fib") || function_name.contains("factorial") {
621 (
622 "Deep".to_string(),
623 "O(2^n)".to_string(),
624 "High - implement memoization".to_string(),
625 )
626 } else {
627 (
628 "Moderate".to_string(),
629 "O(n)".to_string(),
630 "Medium - consider iterative approach".to_string(),
631 )
632 }
633 }
634
635 fn get_memory_recommendation(&self, pattern_type: &str) -> String {
636 match pattern_type {
637 "Loop Allocation" => "Move allocation outside loop or use object pooling".to_string(),
638 "Large Array" => "Consider streaming or chunked processing".to_string(),
639 "Default Capacity" => "Initialize collections with expected capacity".to_string(),
640 _ => "Review memory allocation patterns".to_string(),
641 }
642 }
643
644 fn get_line_info(&self, content: &str, position: usize) -> String {
645 let line_num = content[..position].matches('\n').count() + 1;
646 format!("Line: {}, Position: {}", line_num, position)
647 }
648
649 fn meets_complexity_threshold(&self, complexity: &str, threshold: &str) -> bool {
651 match threshold {
652 "low" => true, "medium" => !complexity.contains("O(1)") && !matches!(complexity, "O(log n)"),
654 "high" => {
655 complexity.contains("O(n²)")
656 || complexity.contains("O(n³)")
657 || complexity.contains("O(n⁴)")
658 || complexity.contains("O(2^n)")
659 || complexity.contains("O(n!)")
660 }
661 _ => true,
662 }
663 }
664
665 pub fn get_performance_recommendations(&self, issues: &[PerformanceIssue]) -> Vec<String> {
667 let mut recommendations = Vec::new();
668
669 if issues.is_empty() {
670 recommendations.push(
671 "No obvious performance issues detected. Continue monitoring with profiling tools."
672 .to_string(),
673 );
674 return recommendations;
675 }
676
677 let mut issue_counts = HashMap::new();
679 let mut _total_impact = 0.0;
680 for issue in issues {
681 *issue_counts.entry(issue.issue_type.clone()).or_insert(0) += 1;
682 if let Some(impact) = issue.impact_score {
683 _total_impact += impact;
684 }
685 }
686
687 let mut priority_issues: Vec<_> = issue_counts.iter().collect();
689 priority_issues.sort_by(|a, b| b.1.cmp(a.1));
690
691 if issue_counts.contains_key("Database Query in Loop") {
693 recommendations.push("HIGH PRIORITY: Eliminate N+1 query problems with batch operations and proper ORM usage".to_string());
694 }
695
696 if issue_counts.contains_key("Exponential Recursion")
697 || issue_counts.contains_key("Factorial Complexity")
698 {
699 recommendations.push("CRITICAL: Implement dynamic programming or iterative solutions for exponential algorithms".to_string());
700 }
701
702 if issue_counts.contains_key("Network Call in Loop") {
703 recommendations.push(
704 "CRITICAL: Implement async/batch processing for network operations".to_string(),
705 );
706 }
707
708 if issue_counts.contains_key("Triple Nested Loop")
710 || issue_counts.contains_key("Quadruple Nested Loop")
711 {
712 recommendations.push("ALGORITHM: Review data structures and consider preprocessing or caching strategies".to_string());
713 }
714
715 if issue_counts.contains_key("Double Nested Loop") {
716 recommendations.push(
717 "ALGORITHM: Consider hash-based lookups or sorting-based optimizations".to_string(),
718 );
719 }
720
721 if issue_counts.contains_key("Large Object Creation in Loop") {
723 recommendations.push(
724 "MEMORY: Implement object pooling or move allocations outside hot paths"
725 .to_string(),
726 );
727 }
728
729 if issue_counts.contains_key("Memory Leak Pattern") {
730 recommendations.push(
731 "MEMORY: Implement proper resource cleanup and bounded collection strategies"
732 .to_string(),
733 );
734 }
735
736 if issue_counts.contains_key("Thread Contention") {
738 recommendations.push("CONCURRENCY: Reduce lock contention with fine-grained locking or lock-free algorithms".to_string());
739 }
740
741 recommendations.extend(self.get_architectural_recommendations(issues));
743
744 recommendations.push(
746 "MONITORING: Implement APM tools for continuous performance monitoring".to_string(),
747 );
748 recommendations.push(
749 "PROFILING: Use language-specific profilers to validate optimizations".to_string(),
750 );
751 recommendations
752 .push("TESTING: Implement performance regression tests in CI/CD pipeline".to_string());
753
754 recommendations
755 }
756
757 pub fn analyze_time_complexity(&self, content: &str) -> Result<Vec<Value>> {
759 let issues = self.analyze_content(content, &["time_complexity".to_string()], "low")?;
760
761 Ok(issues
762 .into_iter()
763 .map(|i| {
764 serde_json::json!({
765 "type": i.issue_type,
766 "severity": i.severity,
767 "description": i.description,
768 "location": i.location,
769 "recommendation": i.recommendation,
770 "complexity": i.complexity_estimate,
771 "impact_score": i.impact_score,
772 "optimization_effort": i.optimization_effort
773 })
774 })
775 .collect())
776 }
777
778 pub fn analyze_memory_usage(&self, content: &str) -> Result<Vec<Value>> {
780 let issues = self.analyze_content(content, &["memory_usage".to_string()], "low")?;
781
782 Ok(issues
783 .into_iter()
784 .map(|i| {
785 serde_json::json!({
786 "type": i.issue_type,
787 "severity": i.severity,
788 "description": i.description,
789 "location": i.location,
790 "recommendation": i.recommendation,
791 "complexity": i.complexity_estimate,
792 "impact_score": i.impact_score,
793 "optimization_effort": i.optimization_effort
794 })
795 })
796 .collect())
797 }
798
799 pub fn detect_performance_hot_spots(&self, content: &str) -> Result<Vec<Value>> {
801 let issues = self.analyze_content(content, &["hot_spots".to_string()], "low")?;
802
803 Ok(issues
804 .into_iter()
805 .map(|i| {
806 serde_json::json!({
807 "type": i.issue_type,
808 "severity": i.severity,
809 "description": i.description,
810 "location": i.location,
811 "recommendation": i.recommendation,
812 "complexity": i.complexity_estimate,
813 "impact_score": i.impact_score,
814 "optimization_effort": i.optimization_effort
815 })
816 })
817 .collect())
818 }
819
820 pub fn detect_concurrency_bottlenecks(&self, content: &str) -> Result<Vec<Value>> {
822 let issues =
823 self.analyze_content(content, &["concurrency_bottlenecks".to_string()], "low")?;
824
825 Ok(issues
826 .into_iter()
827 .map(|i| {
828 serde_json::json!({
829 "type": i.issue_type,
830 "severity": i.severity,
831 "description": i.description,
832 "location": i.location,
833 "recommendation": i.recommendation,
834 "complexity": i.complexity_estimate,
835 "impact_score": i.impact_score,
836 "optimization_effort": i.optimization_effort
837 })
838 })
839 .collect())
840 }
841
842 pub fn comprehensive_analysis(&self, content: &str, language: Option<&str>) -> Result<Value> {
844 let mut all_issues = Vec::new();
845
846 let analysis_types = vec![
848 "time_complexity".to_string(),
849 "memory_usage".to_string(),
850 "hot_spots".to_string(),
851 "concurrency_bottlenecks".to_string(),
852 "algorithm_patterns".to_string(),
853 "regression_patterns".to_string(),
854 ];
855
856 for analysis_type in analysis_types {
857 let issues = self.analyze_content(content, &[analysis_type], "low")?;
858 all_issues.extend(issues);
859 }
860
861 if let Some(lang) = language {
863 if let Some(lang_patterns) = self.language_specific_patterns.get(lang) {
864 for pattern in lang_patterns {
865 for mat in pattern.pattern.find_iter(content) {
866 all_issues.push(PerformanceIssue {
867 issue_type: pattern.name.clone(),
868 severity: pattern.severity.clone(),
869 description: pattern.description.clone(),
870 location: Some(self.get_line_info(content, mat.start())),
871 recommendation: pattern.recommendation.clone(),
872 complexity_estimate: Some(pattern.complexity.clone()),
873 impact_score: Some(pattern.impact_score),
874 optimization_effort: Some(pattern.optimization_effort.clone()),
875 });
876 }
877 }
878 }
879 }
880
881 let recursive_analysis = self.analyze_recursive_complexity(content)?;
883
884 let memory_patterns = self.analyze_memory_patterns(content)?;
886
887 let recommendations = self.get_performance_recommendations(&all_issues);
889 let architectural_recommendations = self.get_architectural_recommendations(&all_issues);
890
891 let total_issues = all_issues.len();
893 let critical_issues = all_issues
894 .iter()
895 .filter(|i| i.severity == "critical")
896 .count();
897 let high_issues = all_issues.iter().filter(|i| i.severity == "high").count();
898 let _total_impact: f64 = all_issues.iter().filter_map(|i| i.impact_score).sum();
899
900 Ok(serde_json::json!({
901 "summary": {
902 "total_issues": total_issues,
903 "critical_issues": critical_issues,
904 "high_issues": high_issues,
905 "total_impact_score": _total_impact,
906 "performance_grade": self.calculate_performance_grade(_total_impact, total_issues)
907 },
908 "issues": all_issues.iter().map(|i| serde_json::json!({
909 "type": i.issue_type,
910 "severity": i.severity,
911 "description": i.description,
912 "location": i.location,
913 "recommendation": i.recommendation,
914 "complexity": i.complexity_estimate,
915 "impact_score": i.impact_score,
916 "optimization_effort": i.optimization_effort
917 })).collect::<Vec<_>>(),
918 "recursive_analysis": recursive_analysis,
919 "memory_patterns": memory_patterns,
920 "recommendations": recommendations,
921 "architectural_recommendations": architectural_recommendations,
922 "language_specific": language.unwrap_or("generic")
923 }))
924 }
925
926 fn calculate_performance_grade(&self, total_impact: f64, issue_count: usize) -> String {
927 let average_impact = if issue_count > 0 {
928 total_impact / issue_count as f64
929 } else {
930 0.0
931 };
932
933 match average_impact {
934 x if x >= 8.0 => "F - Critical Performance Issues".to_string(),
935 x if x >= 6.0 => "D - Significant Performance Issues".to_string(),
936 x if x >= 4.0 => "C - Moderate Performance Issues".to_string(),
937 x if x >= 2.0 => "B - Minor Performance Issues".to_string(),
938 _ => "A - Good Performance".to_string(),
939 }
940 }
941}
942
943impl Default for PerformanceAnalyzer {
944 fn default() -> Self {
945 Self::new()
946 }
947}
948
949#[cfg(test)]
950mod tests {
951 use super::*;
952
953 #[test]
954 fn test_enhanced_nested_loop_detection() {
955 let analyzer = PerformanceAnalyzer::new();
956
957 let code =
958 "for i in range(n): for j in range(n): for k in range(n): for l in range(n): pass";
959 let issues = analyzer
960 .analyze_content(code, &["time_complexity".to_string()], "low")
961 .unwrap();
962
963 assert!(!issues.is_empty());
964 assert!(issues
965 .iter()
966 .any(|i| i.issue_type == "Quadruple Nested Loop"));
967 }
968
969 #[test]
970 fn test_exponential_recursion_detection() {
971 let analyzer = PerformanceAnalyzer::new();
972
973 let code = "def fibonacci(n): return fibonacci(n-1) + fibonacci(n-2)";
974 let issues = analyzer
975 .analyze_content(code, &["time_complexity".to_string()], "low")
976 .unwrap();
977
978 assert!(!issues.is_empty());
979 }
980
981 #[test]
982 fn test_concurrency_bottleneck_detection() {
983 let analyzer = PerformanceAnalyzer::new();
984
985 let code = "synchronized(lock) { for(int i = 0; i < n; i++) { process(i); } }";
986 let issues = analyzer
987 .analyze_content(code, &["concurrency_bottlenecks".to_string()], "low")
988 .unwrap();
989
990 assert!(!issues.is_empty());
991 assert!(issues.iter().any(|i| i.issue_type == "Thread Contention"));
992 }
993
994 #[test]
995 fn test_comprehensive_analysis() {
996 let analyzer = PerformanceAnalyzer::new();
997
998 let code = "for i in range(n): for j in range(n): query('SELECT * FROM table')";
999 let result = analyzer
1000 .comprehensive_analysis(code, Some("python"))
1001 .unwrap();
1002
1003 assert!(result.get("summary").is_some());
1004 assert!(result.get("issues").is_some());
1005 assert!(result.get("recommendations").is_some());
1006 }
1007
1008 #[test]
1009 fn test_memory_pattern_analysis() {
1010 let analyzer = PerformanceAnalyzer::new();
1011
1012 let code = "for i in range(n): obj = new LargeObject()";
1013 let patterns = analyzer.analyze_memory_patterns(code).unwrap();
1014
1015 assert!(!patterns.is_empty());
1016 }
1017
1018 #[test]
1019 fn test_performance_grade_calculation() {
1020 let analyzer = PerformanceAnalyzer::new();
1021
1022 assert_eq!(
1023 analyzer.calculate_performance_grade(10.0, 1),
1024 "F - Critical Performance Issues"
1025 );
1026 assert_eq!(
1027 analyzer.calculate_performance_grade(1.0, 1),
1028 "A - Good Performance"
1029 );
1030 }
1031
1032 #[test]
1033 fn test_database_query_in_loop() {
1034 let analyzer = PerformanceAnalyzer::new();
1035
1036 let code =
1037 "for user in users:\n query(\"SELECT * FROM orders WHERE user_id = ?\", user.id)";
1038 let issues = analyzer
1039 .analyze_content(code, &["hot_spots".to_string()], "low")
1040 .unwrap();
1041
1042 assert!(!issues.is_empty());
1043 assert!(issues
1044 .iter()
1045 .any(|i| i.issue_type == "Database Query in Loop"));
1046 }
1047
1048 #[test]
1049 fn test_string_concatenation() {
1050 let analyzer = PerformanceAnalyzer::new();
1051
1052 let code = "for item in items: result += str(item)";
1053 let issues = analyzer
1054 .analyze_content(code, &["time_complexity".to_string()], "low")
1055 .unwrap();
1056
1057 assert!(!issues.is_empty());
1058 assert!(issues
1059 .iter()
1060 .any(|i| i.issue_type == "Inefficient String Concatenation"));
1061 }
1062
1063 #[test]
1064 fn test_enhanced_complexity_threshold() {
1065 let analyzer = PerformanceAnalyzer::new();
1066
1067 assert!(analyzer.meets_complexity_threshold("O(n²)", "medium"));
1068 assert!(!analyzer.meets_complexity_threshold("O(1)", "medium"));
1069 assert!(analyzer.meets_complexity_threshold("O(n⁴)", "high"));
1070 assert!(analyzer.meets_complexity_threshold("O(2^n)", "high"));
1071 }
1072
1073 #[test]
1074 fn test_enhanced_performance_recommendations() {
1075 let analyzer = PerformanceAnalyzer::new();
1076
1077 let issues = vec![PerformanceIssue {
1078 issue_type: "Database Query in Loop".to_string(),
1079 severity: "critical".to_string(),
1080 description: "Test".to_string(),
1081 location: None,
1082 recommendation: "Test".to_string(),
1083 complexity_estimate: Some("O(n)".to_string()),
1084 impact_score: Some(9.0),
1085 optimization_effort: Some("Medium".to_string()),
1086 }];
1087
1088 let recommendations = analyzer.get_performance_recommendations(&issues);
1089 assert!(!recommendations.is_empty());
1090 assert!(recommendations.iter().any(|r| r.contains("HIGH PRIORITY")));
1091 }
1092}