codeprism_analysis/
performance.rs

1//! Performance analysis module
2
3use anyhow::Result;
4use regex::Regex;
5use serde::Serialize;
6use serde_json::Value;
7use std::collections::HashMap;
8
9/// Performance issue information
10#[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/// Recursive complexity information
23#[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/// Memory allocation pattern
32#[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
40/// Performance analyzer for code analysis
41pub 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        // Enhanced time complexity patterns
71        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        // Enhanced memory usage patterns
147        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        // Enhanced hot spots patterns
206        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        // Concurrency bottleneck patterns
252        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        // Algorithm-specific patterns
288        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        // Performance regression patterns
317        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        // Python-specific patterns
349        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        // JavaScript-specific patterns
378        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        // Java-specific patterns
409        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    /// Analyze content for performance issues with enhanced capabilities
439    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                        // Find all matches, not just the first one
458                        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    /// Analyze recursive function complexity
479    pub fn analyze_recursive_complexity(&self, content: &str) -> Result<Vec<RecursiveComplexity>> {
480        let mut recursive_functions = Vec::new();
481
482        // Pattern for recursive functions (simplified since Rust regex doesn't support backreferences)
483        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                // Check if the function actually calls itself by searching for the function name in the content
490                if content.contains(&format!("{}(", function_name)) {
491                    // Count occurrences to determine if it's likely recursive
492                    let call_count = content.matches(&format!("{}(", function_name)).count();
493                    if call_count > 1 {
494                        // Function definition + at least one call
495                        // Analyze recursion depth and complexity
496                        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    /// Analyze memory allocation patterns
514    pub fn analyze_memory_patterns(&self, content: &str) -> Result<Vec<MemoryPattern>> {
515        let mut patterns = Vec::new();
516
517        // Analyze various memory allocation patterns
518        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    /// Get architectural performance recommendations
555    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        // Architectural recommendations based on issue patterns
565        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        // Specific architectural patterns
584        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        // Simplified complexity estimation - in practice would analyze call patterns
620        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    /// Enhanced complexity threshold checking
650    fn meets_complexity_threshold(&self, complexity: &str, threshold: &str) -> bool {
651        match threshold {
652            "low" => true, // Include all complexities
653            "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    /// Enhanced performance recommendations with architectural guidance
666    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        // Group by issue type and calculate priorities
678        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        // Prioritized recommendations based on impact
688        let mut priority_issues: Vec<_> = issue_counts.iter().collect();
689        priority_issues.sort_by(|a, b| b.1.cmp(a.1));
690
691        // Critical issue recommendations
692        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        // Algorithmic recommendations
709        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        // Memory optimization recommendations
722        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        // Concurrency recommendations
737        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        // General architectural recommendations
742        recommendations.extend(self.get_architectural_recommendations(issues));
743
744        // Tool recommendations
745        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    /// Analyze time complexity issues
758    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    /// Analyze memory usage issues
779    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    /// Detect performance hot spots
800    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    /// Detect concurrency bottlenecks
821    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    /// Comprehensive performance analysis
843    pub fn comprehensive_analysis(&self, content: &str, language: Option<&str>) -> Result<Value> {
844        let mut all_issues = Vec::new();
845
846        // Run all analysis types
847        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        // Add language-specific analysis if specified
862        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        // Analyze recursive complexity
882        let recursive_analysis = self.analyze_recursive_complexity(content)?;
883
884        // Analyze memory patterns
885        let memory_patterns = self.analyze_memory_patterns(content)?;
886
887        // Generate comprehensive recommendations
888        let recommendations = self.get_performance_recommendations(&all_issues);
889        let architectural_recommendations = self.get_architectural_recommendations(&all_issues);
890
891        // Calculate summary statistics
892        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}