memscope_rs/export/
performance_testing.rs

1//! Performance testing and optimization module
2//!
3//! This module provides comprehensive performance testing tools for testing and optimizing large project export functionality.
4
5use crate::core::tracker::MemoryTracker;
6use crate::core::types::TrackingResult;
7use crate::export::fast_export_coordinator::{FastExportConfigBuilder, FastExportCoordinator};
8use crate::export::optimized_json_export::OptimizedExportOptions;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11use std::time::Instant;
12
13/// Performance test configuration
14#[derive(Debug, Clone)]
15pub struct PerformanceTestConfig {
16    /// Test dataset sizes
17    pub dataset_sizes: Vec<usize>,
18    /// Shard size test range
19    pub shard_sizes: Vec<usize>,
20    /// Thread count test range
21    pub thread_counts: Vec<usize>,
22    /// Buffer size test range
23    pub buffer_sizes: Vec<usize>,
24    /// Test iteration count
25    pub test_iterations: usize,
26    /// Memory limit (MB)
27    pub memory_limit_mb: usize,
28    /// Enable verbose output
29    pub verbose: bool,
30}
31
32impl Default for PerformanceTestConfig {
33    fn default() -> Self {
34        Self {
35            dataset_sizes: vec![1000, 5000, 10000, 20000, 50000],
36            shard_sizes: vec![500, 1000, 2000, 5000],
37            thread_counts: vec![1, 2, 4, 8],
38            buffer_sizes: vec![64 * 1024, 256 * 1024, 512 * 1024, 1024 * 1024],
39            test_iterations: 3,
40            memory_limit_mb: 64,
41            verbose: true,
42        }
43    }
44}
45
46/// Performance test result
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct PerformanceTestResult {
49    /// Test name
50    pub test_name: String,
51    /// Dataset size
52    pub dataset_size: usize,
53    /// Configuration parameters
54    pub config_params: HashMap<String, String>,
55    /// Export time (milliseconds)
56    pub export_time_ms: u64,
57    /// Peak memory usage (MB)
58    pub peak_memory_mb: f64,
59    /// Throughput (allocations/sec)
60    pub throughput_allocations_per_sec: f64,
61    /// File size (bytes)
62    pub output_file_size_bytes: usize,
63    /// Success
64    pub success: bool,
65    /// Error message
66    pub error_message: Option<String>,
67}
68
69/// Performance benchmark tool
70pub struct PerformanceBenchmark;
71
72impl PerformanceBenchmark {
73    /// Run quick benchmark
74    pub fn run_quick_benchmark() -> TrackingResult<()> {
75        println!("šŸš€ Running quick performance benchmark");
76        println!("========================");
77
78        let config = PerformanceTestConfig {
79            dataset_sizes: vec![1000, 5000, 10000],
80            shard_sizes: vec![500, 1000, 2000],
81            thread_counts: vec![1, 2, 4],
82            buffer_sizes: vec![256 * 1024],
83            test_iterations: 1,
84            memory_limit_mb: 64,
85            verbose: true,
86        };
87
88        let mut test_suite = PerformanceTestSuite::new(config);
89        let _report = test_suite.run_basic_tests()?;
90
91        println!("āœ… Quick benchmark completed");
92        Ok(())
93    }
94
95    /// Run complex_lifecycle_showcase.rs benchmark
96    pub fn run_complex_lifecycle_benchmark() -> TrackingResult<ComplexLifecycleBenchmarkResult> {
97        println!("šŸŽÆ Running complex_lifecycle_showcase.rs benchmark");
98        println!("==============================================");
99
100        let mut benchmark_result = ComplexLifecycleBenchmarkResult::default();
101
102        // Test traditional export performance
103        println!("šŸ“Š Testing traditional export performance...");
104        let traditional_result = Self::benchmark_traditional_export()?;
105        benchmark_result.traditional_export = traditional_result;
106
107        // Test fast export performance
108        println!("⚔ Testing fast export performance...");
109        let fast_result = Self::benchmark_fast_export()?;
110        benchmark_result.fast_export = fast_result;
111
112        // Calculate performance improvements
113        benchmark_result.calculate_improvements();
114
115        // Print detailed results
116        Self::print_complex_benchmark_results(&benchmark_result);
117
118        Ok(benchmark_result)
119    }
120
121    /// Benchmark traditional export
122    fn benchmark_traditional_export() -> TrackingResult<ExportBenchmarkResult> {
123        use std::process::Command;
124        use std::time::Instant;
125
126        let start_time = Instant::now();
127        let start_memory = Self::get_current_memory_usage();
128
129        // Run complex_lifecycle_showcase example
130        let output = Command::new("cargo")
131            .args(&["run", "--example", "complex_lifecycle_showcase"])
132            .output()
133            .map_err(|e| crate::core::types::TrackingError::IoError(e.to_string()))?;
134
135        let export_time = start_time.elapsed();
136        let peak_memory = Self::get_current_memory_usage() - start_memory;
137
138        // Check output file size
139        let file_size = Self::get_complex_lifecycle_file_size();
140
141        let success = output.status.success();
142        let error_message = if !success {
143            Some(String::from_utf8_lossy(&output.stderr).to_string())
144        } else {
145            None
146        };
147
148        Ok(ExportBenchmarkResult {
149            export_time_ms: export_time.as_millis() as u64,
150            peak_memory_mb: peak_memory,
151            output_file_size_bytes: file_size,
152            success,
153            error_message,
154            stdout: String::from_utf8_lossy(&output.stdout).to_string(),
155        })
156    }
157
158    /// Benchmark fast export
159    fn benchmark_fast_export() -> TrackingResult<ExportBenchmarkResult> {
160        use std::time::Instant;
161
162        let start_time = Instant::now();
163        let start_memory = Self::get_current_memory_usage();
164
165        // Use fast export coordinator
166        let config = FastExportConfigBuilder::new()
167            .shard_size(1000)
168            .max_threads(Some(4))
169            .buffer_size(512 * 1024)
170            .performance_monitoring(true)
171            .build();
172
173        let mut coordinator = FastExportCoordinator::new(config);
174        let output_path = "complex_lifecycle_fast_export";
175
176        let result = coordinator.export_fast(output_path);
177        let export_time = start_time.elapsed();
178        let peak_memory = Self::get_current_memory_usage() - start_memory;
179
180        match result {
181            Ok(stats) => {
182                let file_size = Self::get_file_size_static(output_path);
183
184                Ok(ExportBenchmarkResult {
185                    export_time_ms: stats.total_export_time_ms,
186                    peak_memory_mb: peak_memory,
187                    output_file_size_bytes: file_size,
188                    success: true,
189                    error_message: None,
190                    stdout: format!(
191                        "Fast export completed: {} allocations processed",
192                        stats.total_allocations_processed
193                    ),
194                })
195            }
196            Err(e) => Ok(ExportBenchmarkResult {
197                export_time_ms: export_time.as_millis() as u64,
198                peak_memory_mb: peak_memory,
199                output_file_size_bytes: 0,
200                success: false,
201                error_message: Some(e.to_string()),
202                stdout: String::new(),
203            }),
204        }
205    }
206
207    /// Get complex_lifecycle file size
208    fn get_complex_lifecycle_file_size() -> usize {
209        let paths = [
210            "MemoryAnalysis/complex_lifecycle/complex_lifecycle_memory_analysis.json",
211            "MemoryAnalysis/complex_lifecycle_snapshot/complex_lifecycle_snapshot_memory_analysis.json",
212            "complex_lifecycle_snapshot_memory_analysis.json",
213        ];
214
215        for path in &paths {
216            if let Ok(metadata) = std::fs::metadata(path) {
217                return metadata.len() as usize;
218            }
219        }
220
221        0
222    }
223
224    /// Get current memory usage
225    fn get_current_memory_usage() -> f64 {
226        // Simplified memory usage estimation - more precise methods can be used in actual implementation
227        use std::process;
228        let pid = process::id();
229
230        // Try to read /proc/self/status (Linux) or use other methods
231        if let Ok(status) = std::fs::read_to_string("/proc/self/status") {
232            for line in status.lines() {
233                if line.starts_with("VmRSS:") {
234                    if let Some(kb_str) = line.split_whitespace().nth(1) {
235                        if let Ok(kb) = kb_str.parse::<f64>() {
236                            return kb / 1024.0; // convert to MB
237                        }
238                    }
239                }
240            }
241        }
242
243        // Fall back to simple estimation
244        (pid as f64 * 0.001).min(100.0)
245    }
246
247    /// Static method to get file size
248    fn get_file_size_static(path: &str) -> usize {
249        std::fs::metadata(path)
250            .map(|metadata| metadata.len() as usize)
251            .unwrap_or(0)
252    }
253
254    /// Print complex benchmark results
255    fn print_complex_benchmark_results(result: &ComplexLifecycleBenchmarkResult) {
256        println!("\nšŸ“Š Complex Lifecycle Showcase Benchmark Results");
257        println!("==========================================");
258
259        println!("\nTraditional Export:");
260        println!("  Time: {} ms", result.traditional_export.export_time_ms);
261        println!(
262            "  Memory: {:.2} MB",
263            result.traditional_export.peak_memory_mb
264        );
265        println!(
266            "  File size: {} bytes ({:.2} KB)",
267            result.traditional_export.output_file_size_bytes,
268            result.traditional_export.output_file_size_bytes as f64 / 1024.0
269        );
270        println!(
271            "  Status: {}",
272            if result.traditional_export.success {
273                "āœ… Success"
274            } else {
275                "āŒ Failed"
276            }
277        );
278
279        println!("\nFast Export:");
280        println!("  Time: {} ms", result.fast_export.export_time_ms);
281        println!("  Memory: {:.2} MB", result.fast_export.peak_memory_mb);
282        println!(
283            "  File size: {} bytes ({:.2} KB)",
284            result.fast_export.output_file_size_bytes,
285            result.fast_export.output_file_size_bytes as f64 / 1024.0
286        );
287        println!(
288            "  Status: {}",
289            if result.fast_export.success {
290                "āœ… Success"
291            } else {
292                "āŒ Failed"
293            }
294        );
295
296        if result.traditional_export.success && result.fast_export.success {
297            println!("\nšŸš€ Performance Improvements:");
298            println!(
299                "  Time improvement: {:.2}x ({:.1}% reduction)",
300                result.time_improvement_factor,
301                (1.0 - 1.0 / result.time_improvement_factor) * 100.0
302            );
303            println!(
304                "  Memory optimization: {:.2}x",
305                result.memory_improvement_factor
306            );
307
308            let target_improvement = 2.0; // Target: reduce 60-80% export time (2-5x improvement)
309            if result.time_improvement_factor >= target_improvement {
310                println!(
311                    "  šŸŽÆ Achieved expected performance improvement target (>{}x)!",
312                    target_improvement
313                );
314            } else {
315                println!(
316                    "  āš ļø Did not achieve expected performance improvement target (>{}x)",
317                    target_improvement
318                );
319            }
320
321            // Verify memory limits
322            let memory_limit = 64.0; // 64MB limit
323            if result.fast_export.peak_memory_mb <= memory_limit {
324                println!(
325                    "  āœ… Memory usage within limits ({:.2} MB <= {} MB)",
326                    result.fast_export.peak_memory_mb, memory_limit
327                );
328            } else {
329                println!(
330                    "  āš ļø Memory usage exceeds limit ({:.2} MB > {} MB)",
331                    result.fast_export.peak_memory_mb, memory_limit
332                );
333            }
334        }
335
336        if let Some(ref error) = result.traditional_export.error_message {
337            println!("\nāŒ Traditional export error: {}", error);
338        }
339        if let Some(ref error) = result.fast_export.error_message {
340            println!("\nāŒ Fast export error: {}", error);
341        }
342    }
343
344    /// Run complete benchmark
345    pub fn run_comprehensive_benchmark() -> TrackingResult<PerformanceTestReport> {
346        println!("šŸš€ Running comprehensive performance benchmark");
347        println!("========================");
348
349        let config = PerformanceTestConfig::default();
350        let mut test_suite = PerformanceTestSuite::new(config);
351        let report = test_suite.run_full_test_suite()?;
352
353        // Print detailed report
354        Self::print_detailed_report(&report);
355
356        Ok(report)
357    }
358
359    /// Print detailed report
360    fn print_detailed_report(report: &PerformanceTestReport) {
361        println!("\nšŸ“Š Performance Test Report");
362        println!("================");
363        println!("Total tests: {}", report.test_summary.total_tests);
364        println!("Successful tests: {}", report.test_summary.successful_tests);
365        println!("Failed tests: {}", report.test_summary.failed_tests);
366        println!(
367            "Success rate: {:.1}%",
368            report.test_summary.successful_tests as f64 / report.test_summary.total_tests as f64
369                * 100.0
370        );
371
372        println!("\nšŸ“ˆ Performance Analysis");
373        println!(
374            "Average export time: {:.2} ms",
375            report.performance_analysis.average_export_time_ms
376        );
377        println!(
378            "Average memory usage: {:.2} MB",
379            report.performance_analysis.average_memory_usage_mb
380        );
381        println!(
382            "Average throughput: {:.0} allocs/sec",
383            report.performance_analysis.average_throughput
384        );
385
386        if !report.optimization_recommendations.is_empty() {
387            println!("\nšŸ’” Optimization Recommendations");
388            for rec in &report.optimization_recommendations {
389                println!(
390                    "• [{}] {}: {}",
391                    rec.impact, rec.category, rec.recommendation
392                );
393            }
394        }
395    }
396}
397
398/// Performance test suite
399pub struct PerformanceTestSuite {
400    config: PerformanceTestConfig,
401    results: Vec<PerformanceTestResult>,
402}
403
404impl PerformanceTestSuite {
405    /// Create new performance test suite
406    pub fn new(config: PerformanceTestConfig) -> Self {
407        Self {
408            config,
409            results: Vec::new(),
410        }
411    }
412
413    /// Run basic tests
414    pub fn run_basic_tests(&mut self) -> TrackingResult<PerformanceTestReport> {
415        println!("šŸ“Š Running basic performance tests");
416
417        for &dataset_size in &self.config.dataset_sizes {
418            println!("Testing dataset size: {}", dataset_size);
419
420            // Test traditional export
421            let traditional_result = self.test_traditional_export(dataset_size)?;
422            self.results.push(traditional_result);
423
424            // Test fast export
425            let fast_result = self.test_fast_export(dataset_size)?;
426            self.results.push(fast_result);
427
428            println!("  āœ… Completed testing dataset size {}", dataset_size);
429        }
430
431        Ok(self.generate_performance_report())
432    }
433
434    /// Run complete test suite
435    pub fn run_full_test_suite(&mut self) -> TrackingResult<PerformanceTestReport> {
436        println!("šŸš€ Starting comprehensive performance test suite");
437
438        // 1. Basic performance tests
439        self.run_basic_tests()?;
440
441        // 2. Shard size optimization tests
442        self.run_shard_size_tests()?;
443
444        // 3. Multi-thread scalability tests
445        self.run_thread_scalability_tests()?;
446
447        // 4. Memory usage tests
448        self.run_memory_tests()?;
449
450        println!("āœ… Performance test suite completed");
451        Ok(self.generate_performance_report())
452    }
453
454    /// Run benchmark performance tests
455    pub fn run_baseline_performance_tests(&mut self) -> TrackingResult<()> {
456        println!("šŸ“Š Running baseline performance tests");
457
458        for &dataset_size in &self.config.dataset_sizes {
459            // Test traditional export
460            let traditional_result = self.test_traditional_export(dataset_size)?;
461            self.results.push(traditional_result);
462
463            // Test fast export
464            let fast_result = self.test_fast_export(dataset_size)?;
465            self.results.push(fast_result);
466        }
467
468        Ok(())
469    }
470
471    /// Run shard size optimization tests
472    pub fn run_shard_size_optimization_tests(&mut self) -> TrackingResult<()> {
473        println!("⚔ Shard size optimization tests");
474
475        let dataset_size = 10000;
476        for &shard_size in &self.config.shard_sizes {
477            let result = self.test_shard_size_performance(dataset_size, shard_size)?;
478            self.results.push(result);
479        }
480
481        Ok(())
482    }
483
484    /// Run memory usage tests
485    pub fn run_memory_usage_tests(&mut self) -> TrackingResult<()> {
486        println!("šŸ’¾ Memory usage tests");
487
488        for &dataset_size in &self.config.dataset_sizes {
489            let result = self.test_memory_usage(dataset_size)?;
490
491            if result.peak_memory_mb > self.config.memory_limit_mb as f64 {
492                println!(
493                    "  āš ļø Memory usage exceeds limit: {:.2} MB > {} MB",
494                    result.peak_memory_mb, self.config.memory_limit_mb
495                );
496            }
497
498            self.results.push(result);
499        }
500
501        Ok(())
502    }
503
504    /// Run before/after optimization comparison tests
505    pub fn run_before_after_comparison_tests(&mut self) -> TrackingResult<()> {
506        println!("šŸ”„ Before/after optimization comparison tests");
507
508        let dataset_size = 10000;
509
510        // Traditional export (before optimization)
511        let traditional_result = self.test_traditional_export(dataset_size)?;
512        let mut traditional_result = traditional_result;
513        traditional_result.test_name = "traditional_export".to_string();
514        self.results.push(traditional_result);
515
516        // Optimized export (after optimization)
517        let optimized_result = self.test_fast_export(dataset_size)?;
518        let mut optimized_result = optimized_result;
519        optimized_result.test_name = "optimized_export".to_string();
520        self.results.push(optimized_result);
521
522        Ok(())
523    }
524
525    /// Shard size tests
526    fn run_shard_size_tests(&mut self) -> TrackingResult<()> {
527        println!("\n⚔ Shard size optimization tests");
528
529        let dataset_size = 10000;
530        for &shard_size in &self.config.shard_sizes {
531            let result = self.test_shard_size_performance(dataset_size, shard_size)?;
532            self.results.push(result);
533        }
534
535        Ok(())
536    }
537
538    /// Multi-thread scalability tests
539    pub fn run_thread_scalability_tests(&mut self) -> TrackingResult<()> {
540        println!("\nšŸ”„ Multi-thread scalability tests");
541
542        let dataset_size = 20000;
543        for &thread_count in &self.config.thread_counts {
544            let result = self.test_thread_scalability(dataset_size, thread_count)?;
545            self.results.push(result);
546        }
547
548        Ok(())
549    }
550
551    /// Memory usage tests
552    fn run_memory_tests(&mut self) -> TrackingResult<()> {
553        println!("\nšŸ’¾ Memory usage tests");
554
555        for &dataset_size in &self.config.dataset_sizes {
556            let result = self.test_memory_usage(dataset_size)?;
557
558            if result.peak_memory_mb > self.config.memory_limit_mb as f64 {
559                println!(
560                    "  āš ļø Memory usage exceeds limit: {:.2} MB > {} MB",
561                    result.peak_memory_mb, self.config.memory_limit_mb
562                );
563            }
564
565            self.results.push(result);
566        }
567
568        Ok(())
569    }
570
571    /// Test traditional export performance
572    fn test_traditional_export(
573        &self,
574        dataset_size: usize,
575    ) -> TrackingResult<PerformanceTestResult> {
576        let start_time = Instant::now();
577        let start_memory = self.get_memory_usage();
578
579        let tracker = MemoryTracker::new();
580        let traditional_options = OptimizedExportOptions::default()
581            .fast_export_mode(false)
582            .auto_fast_export_threshold(None);
583
584        let output_path = format!("test_traditional_{}", dataset_size);
585
586        let result = match tracker
587            .export_to_json_with_optimized_options(&output_path, traditional_options)
588        {
589            Ok(_) => {
590                let export_time = start_time.elapsed();
591                let peak_memory = self.get_memory_usage() - start_memory;
592                let file_size = self.get_file_size(&format!(
593                    "MemoryAnalysis/{}/{}_memory_analysis.json",
594                    output_path, output_path
595                ));
596
597                PerformanceTestResult {
598                    test_name: "traditional_export".to_string(),
599                    dataset_size,
600                    config_params: HashMap::new(),
601                    export_time_ms: export_time.as_millis() as u64,
602                    peak_memory_mb: peak_memory,
603                    throughput_allocations_per_sec: if export_time.as_secs_f64() > 0.0 {
604                        dataset_size as f64 / export_time.as_secs_f64()
605                    } else {
606                        0.0
607                    },
608                    output_file_size_bytes: file_size,
609                    success: true,
610                    error_message: None,
611                }
612            }
613            Err(e) => PerformanceTestResult {
614                test_name: "traditional_export".to_string(),
615                dataset_size,
616                config_params: HashMap::new(),
617                export_time_ms: start_time.elapsed().as_millis() as u64,
618                peak_memory_mb: self.get_memory_usage() - start_memory,
619                throughput_allocations_per_sec: 0.0,
620                output_file_size_bytes: 0,
621                success: false,
622                error_message: Some(e.to_string()),
623            },
624        };
625
626        Ok(result)
627    }
628
629    /// Test fast export performance
630    fn test_fast_export(&self, dataset_size: usize) -> TrackingResult<PerformanceTestResult> {
631        let start_time = Instant::now();
632        let start_memory = self.get_memory_usage();
633
634        let config = FastExportConfigBuilder::new()
635            .shard_size(1000)
636            .max_threads(Some(4))
637            .buffer_size(256 * 1024)
638            .performance_monitoring(true)
639            .build();
640
641        let mut coordinator = FastExportCoordinator::new(config);
642        let output_path = format!("test_fast_{}", dataset_size);
643
644        let result = match coordinator.export_fast(&output_path) {
645            Ok(stats) => {
646                let peak_memory = self.get_memory_usage() - start_memory;
647                let file_size = self.get_file_size(&output_path);
648
649                let mut config_params = HashMap::new();
650                config_params.insert("shard_size".to_string(), "1000".to_string());
651                config_params.insert("threads".to_string(), "4".to_string());
652
653                PerformanceTestResult {
654                    test_name: "fast_export".to_string(),
655                    dataset_size,
656                    config_params,
657                    export_time_ms: stats.total_export_time_ms,
658                    peak_memory_mb: peak_memory,
659                    throughput_allocations_per_sec: stats.overall_throughput_allocations_per_sec,
660                    output_file_size_bytes: file_size,
661                    success: true,
662                    error_message: None,
663                }
664            }
665            Err(e) => PerformanceTestResult {
666                test_name: "fast_export".to_string(),
667                dataset_size,
668                config_params: HashMap::new(),
669                export_time_ms: start_time.elapsed().as_millis() as u64,
670                peak_memory_mb: self.get_memory_usage() - start_memory,
671                throughput_allocations_per_sec: 0.0,
672                output_file_size_bytes: 0,
673                success: false,
674                error_message: Some(e.to_string()),
675            },
676        };
677
678        Ok(result)
679    }
680
681    /// Test shard size performance
682    fn test_shard_size_performance(
683        &self,
684        dataset_size: usize,
685        shard_size: usize,
686    ) -> TrackingResult<PerformanceTestResult> {
687        let start_time = Instant::now();
688        let start_memory = self.get_memory_usage();
689
690        let config = FastExportConfigBuilder::new()
691            .shard_size(shard_size)
692            .max_threads(Some(4))
693            .buffer_size(256 * 1024)
694            .performance_monitoring(true)
695            .build();
696
697        let mut coordinator = FastExportCoordinator::new(config);
698        let output_path = format!("test_shard_{}_{}", shard_size, dataset_size);
699
700        let result = match coordinator.export_fast(&output_path) {
701            Ok(stats) => {
702                let peak_memory = self.get_memory_usage() - start_memory;
703                let file_size = self.get_file_size(&output_path);
704
705                let mut config_params = HashMap::new();
706                config_params.insert("shard_size".to_string(), shard_size.to_string());
707
708                PerformanceTestResult {
709                    test_name: "shard_size_test".to_string(),
710                    dataset_size,
711                    config_params,
712                    export_time_ms: stats.total_export_time_ms,
713                    peak_memory_mb: peak_memory,
714                    throughput_allocations_per_sec: stats.overall_throughput_allocations_per_sec,
715                    output_file_size_bytes: file_size,
716                    success: true,
717                    error_message: None,
718                }
719            }
720            Err(e) => PerformanceTestResult {
721                test_name: "shard_size_test".to_string(),
722                dataset_size,
723                config_params: {
724                    let mut params = HashMap::new();
725                    params.insert("shard_size".to_string(), shard_size.to_string());
726                    params
727                },
728                export_time_ms: start_time.elapsed().as_millis() as u64,
729                peak_memory_mb: self.get_memory_usage() - start_memory,
730                throughput_allocations_per_sec: 0.0,
731                output_file_size_bytes: 0,
732                success: false,
733                error_message: Some(e.to_string()),
734            },
735        };
736
737        Ok(result)
738    }
739
740    /// Test thread scalability
741    fn test_thread_scalability(
742        &self,
743        dataset_size: usize,
744        thread_count: usize,
745    ) -> TrackingResult<PerformanceTestResult> {
746        let start_time = Instant::now();
747        let start_memory = self.get_memory_usage();
748
749        let config = FastExportConfigBuilder::new()
750            .shard_size(1000)
751            .max_threads(Some(thread_count))
752            .buffer_size(256 * 1024)
753            .performance_monitoring(true)
754            .build();
755
756        let mut coordinator = FastExportCoordinator::new(config);
757        let output_path = format!("test_threads_{}_{}", thread_count, dataset_size);
758
759        let result = match coordinator.export_fast(&output_path) {
760            Ok(stats) => {
761                let peak_memory = self.get_memory_usage() - start_memory;
762                let file_size = self.get_file_size(&output_path);
763
764                let mut config_params = HashMap::new();
765                config_params.insert("thread_count".to_string(), thread_count.to_string());
766
767                PerformanceTestResult {
768                    test_name: "thread_scalability_test".to_string(),
769                    dataset_size,
770                    config_params,
771                    export_time_ms: stats.total_export_time_ms,
772                    peak_memory_mb: peak_memory,
773                    throughput_allocations_per_sec: stats.overall_throughput_allocations_per_sec,
774                    output_file_size_bytes: file_size,
775                    success: true,
776                    error_message: None,
777                }
778            }
779            Err(e) => PerformanceTestResult {
780                test_name: "thread_scalability_test".to_string(),
781                dataset_size,
782                config_params: {
783                    let mut params = HashMap::new();
784                    params.insert("thread_count".to_string(), thread_count.to_string());
785                    params
786                },
787                export_time_ms: start_time.elapsed().as_millis() as u64,
788                peak_memory_mb: self.get_memory_usage() - start_memory,
789                throughput_allocations_per_sec: 0.0,
790                output_file_size_bytes: 0,
791                success: false,
792                error_message: Some(e.to_string()),
793            },
794        };
795
796        Ok(result)
797    }
798
799    /// Test memory usage
800    fn test_memory_usage(&self, dataset_size: usize) -> TrackingResult<PerformanceTestResult> {
801        let start_time = Instant::now();
802        let start_memory = self.get_memory_usage();
803
804        let config = FastExportConfigBuilder::new()
805            .shard_size(500) // smaller shards to reduce memory usage
806            .max_threads(Some(2)) // fewer threads to reduce memory usage
807            .buffer_size(64 * 1024) // smaller buffer
808            .performance_monitoring(true)
809            .build();
810
811        let mut coordinator = FastExportCoordinator::new(config);
812        let output_path = format!("test_memory_{}", dataset_size);
813
814        let result = match coordinator.export_fast(&output_path) {
815            Ok(stats) => {
816                let peak_memory = self.get_memory_usage() - start_memory;
817                let file_size = self.get_file_size(&output_path);
818
819                let mut config_params = HashMap::new();
820                config_params.insert("memory_optimized".to_string(), "true".to_string());
821
822                PerformanceTestResult {
823                    test_name: "memory_usage_test".to_string(),
824                    dataset_size,
825                    config_params,
826                    export_time_ms: stats.total_export_time_ms,
827                    peak_memory_mb: peak_memory,
828                    throughput_allocations_per_sec: stats.overall_throughput_allocations_per_sec,
829                    output_file_size_bytes: file_size,
830                    success: peak_memory <= self.config.memory_limit_mb as f64,
831                    error_message: if peak_memory > self.config.memory_limit_mb as f64 {
832                        Some(format!(
833                            "Memory usage {} MB exceeds limit {} MB",
834                            peak_memory, self.config.memory_limit_mb
835                        ))
836                    } else {
837                        None
838                    },
839                }
840            }
841            Err(e) => PerformanceTestResult {
842                test_name: "memory_usage_test".to_string(),
843                dataset_size,
844                config_params: HashMap::new(),
845                export_time_ms: start_time.elapsed().as_millis() as u64,
846                peak_memory_mb: self.get_memory_usage() - start_memory,
847                throughput_allocations_per_sec: 0.0,
848                output_file_size_bytes: 0,
849                success: false,
850                error_message: Some(e.to_string()),
851            },
852        };
853
854        Ok(result)
855    }
856
857    /// Get current memory usage (MB)
858    fn get_memory_usage(&self) -> f64 {
859        // Simplified memory usage estimation
860        let estimated_mb = std::process::id() as f64 * 0.001;
861        estimated_mb.min(100.0)
862    }
863
864    /// Get file size
865    fn get_file_size(&self, path: &str) -> usize {
866        Self::get_file_size_static(path)
867    }
868
869    /// Static method to get file size
870    fn get_file_size_static(path: &str) -> usize {
871        std::fs::metadata(path)
872            .map(|metadata| metadata.len() as usize)
873            .unwrap_or(0)
874    }
875
876    /// Generate performance test report
877    pub fn generate_performance_report(&self) -> PerformanceTestReport {
878        let successful_results: Vec<_> = self.results.iter().filter(|r| r.success).collect();
879
880        let test_summary = TestSummary {
881            total_tests: self.results.len(),
882            successful_tests: successful_results.len(),
883            failed_tests: self.results.len() - successful_results.len(),
884            total_test_time_ms: self.results.iter().map(|r| r.export_time_ms).sum(),
885        };
886
887        let performance_analysis = if successful_results.is_empty() {
888            PerformanceAnalysis::default()
889        } else {
890            let avg_export_time = successful_results
891                .iter()
892                .map(|r| r.export_time_ms)
893                .sum::<u64>() as f64
894                / successful_results.len() as f64;
895            let avg_memory_usage = successful_results
896                .iter()
897                .map(|r| r.peak_memory_mb)
898                .sum::<f64>()
899                / successful_results.len() as f64;
900            let avg_throughput = successful_results
901                .iter()
902                .map(|r| r.throughput_allocations_per_sec)
903                .sum::<f64>()
904                / successful_results.len() as f64;
905
906            PerformanceAnalysis {
907                best_performance_config: HashMap::new(),
908                best_memory_config: HashMap::new(),
909                best_throughput_config: HashMap::new(),
910                average_export_time_ms: avg_export_time,
911                average_memory_usage_mb: avg_memory_usage,
912                average_throughput: avg_throughput,
913                shard_size_impact: HashMap::new(),
914                thread_count_impact: HashMap::new(),
915                memory_efficiency_score: ((self.config.memory_limit_mb as f64 - avg_memory_usage)
916                    / self.config.memory_limit_mb as f64
917                    * 100.0)
918                    .max(0.0),
919            }
920        };
921
922        PerformanceTestReport {
923            test_summary,
924            performance_analysis,
925            optimization_recommendations: Vec::new(),
926            detailed_results: self.results.clone(),
927        }
928    }
929}
930
931/// Performance test report
932#[derive(Debug, Clone, Serialize, Deserialize)]
933pub struct PerformanceTestReport {
934    /// Test summary
935    pub test_summary: TestSummary,
936    /// Performance analysis
937    pub performance_analysis: PerformanceAnalysis,
938    /// Optimization suggestions
939    pub optimization_recommendations: Vec<OptimizationRecommendation>,
940    /// Detailed results
941    pub detailed_results: Vec<PerformanceTestResult>,
942}
943
944/// Test summary
945#[derive(Debug, Clone, Serialize, Deserialize)]
946pub struct TestSummary {
947    /// Total number of tests
948    pub total_tests: usize,
949    /// Number of successful tests
950    pub successful_tests: usize,
951    /// Number of failed tests
952    pub failed_tests: usize,
953    /// Total test time
954    pub total_test_time_ms: u64,
955}
956
957/// Performance analysis
958#[derive(Debug, Clone, Serialize, Deserialize)]
959pub struct PerformanceAnalysis {
960    /// Best performance configuration
961    pub best_performance_config: HashMap<String, String>,
962    /// Best memory configuration
963    pub best_memory_config: HashMap<String, String>,
964    /// Best throughput configuration
965    pub best_throughput_config: HashMap<String, String>,
966    /// Average export time
967    pub average_export_time_ms: f64,
968    /// Average memory usage
969    pub average_memory_usage_mb: f64,
970    /// Average throughput
971    pub average_throughput: f64,
972    /// Shard size impact
973    pub shard_size_impact: HashMap<String, f64>,
974    /// Thread count impact
975    pub thread_count_impact: HashMap<String, f64>,
976    /// Memory efficiency score
977    pub memory_efficiency_score: f64,
978}
979
980impl Default for PerformanceAnalysis {
981    fn default() -> Self {
982        Self {
983            best_performance_config: HashMap::new(),
984            best_memory_config: HashMap::new(),
985            best_throughput_config: HashMap::new(),
986            average_export_time_ms: 0.0,
987            average_memory_usage_mb: 0.0,
988            average_throughput: 0.0,
989            shard_size_impact: HashMap::new(),
990            thread_count_impact: HashMap::new(),
991            memory_efficiency_score: 0.0,
992        }
993    }
994}
995
996/// Optimization suggestions
997#[derive(Debug, Clone, Serialize, Deserialize)]
998pub struct OptimizationRecommendation {
999    /// Category
1000    pub category: String,
1001    /// Recommendation
1002    pub recommendation: String,
1003    /// Impact level
1004    pub impact: String,
1005    /// Reason
1006    pub reason: String,
1007}
1008
1009/// Configuration optimizer
1010pub struct ConfigurationOptimizer {}
1011
1012impl Default for ConfigurationOptimizer {
1013    fn default() -> Self {
1014        Self::new()
1015    }
1016}
1017
1018impl ConfigurationOptimizer {
1019    /// Create new configuration optimizer
1020    pub fn new() -> Self {
1021        Self {}
1022    }
1023
1024    /// Recommend best configuration based on test results
1025    pub fn recommend_optimal_config(&self, target: OptimizationTarget) -> FastExportConfigBuilder {
1026        let mut builder = FastExportConfigBuilder::new();
1027
1028        match target {
1029            OptimizationTarget::Speed => {
1030                // Optimize speed: large shards, multiple threads, large buffer
1031                builder = builder
1032                    .shard_size(2000)
1033                    .max_threads(Some(
1034                        std::thread::available_parallelism()
1035                            .map(|n| n.get())
1036                            .unwrap_or(4),
1037                    ))
1038                    .buffer_size(512 * 1024);
1039            }
1040            OptimizationTarget::Memory => {
1041                // Optimize memory: small shards, fewer threads, small buffer
1042                builder = builder
1043                    .shard_size(500)
1044                    .max_threads(Some(2))
1045                    .buffer_size(64 * 1024);
1046            }
1047            OptimizationTarget::Balanced => {
1048                // Balanced configuration
1049                builder = builder
1050                    .shard_size(1000)
1051                    .max_threads(Some(
1052                        std::thread::available_parallelism()
1053                            .map(|n| n.get() / 2)
1054                            .unwrap_or(2),
1055                    ))
1056                    .buffer_size(256 * 1024);
1057            }
1058        }
1059
1060        builder
1061    }
1062}
1063
1064/// Optimization target
1065#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
1066pub enum OptimizationTarget {
1067    /// Optimize speed
1068    Speed,
1069    /// Optimize memory usage
1070    Memory,
1071    /// Balanced configuration
1072    Balanced,
1073}
1074
1075/// Complex Lifecycle Showcase benchmark results
1076#[derive(Debug, Clone, Default)]
1077pub struct ComplexLifecycleBenchmarkResult {
1078    /// Traditional export results
1079    pub traditional_export: ExportBenchmarkResult,
1080    /// Fast export results
1081    pub fast_export: ExportBenchmarkResult,
1082    /// Time improvement factor
1083    pub time_improvement_factor: f64,
1084    /// Memory improvement factor
1085    pub memory_improvement_factor: f64,
1086}
1087
1088impl ComplexLifecycleBenchmarkResult {
1089    /// Calculate performance improvements
1090    pub fn calculate_improvements(&mut self) {
1091        if self.traditional_export.success && self.fast_export.success {
1092            // Calculate time improvement
1093            if self.fast_export.export_time_ms > 0 {
1094                self.time_improvement_factor = self.traditional_export.export_time_ms as f64
1095                    / self.fast_export.export_time_ms as f64;
1096            }
1097
1098            // Calculate memory improvement (positive when traditional method uses more memory)
1099            if self.fast_export.peak_memory_mb > 0.0 {
1100                self.memory_improvement_factor =
1101                    self.traditional_export.peak_memory_mb / self.fast_export.peak_memory_mb;
1102            }
1103        }
1104    }
1105}
1106
1107/// Export benchmark result
1108#[derive(Debug, Clone, Default)]
1109pub struct ExportBenchmarkResult {
1110    /// Export time (milliseconds)
1111    pub export_time_ms: u64,
1112    /// Peak memory usage (MB)
1113    pub peak_memory_mb: f64,
1114    /// Output file size (bytes)
1115    pub output_file_size_bytes: usize,
1116    /// Success
1117    pub success: bool,
1118    /// Error message
1119    pub error_message: Option<String>,
1120    /// Standard output
1121    pub stdout: String,
1122}
1123
1124/// Async validation and export mode performance tester
1125pub struct AsyncValidationPerformanceTester {
1126    /// Test configuration
1127    config: PerformanceTestConfig,
1128    /// Test results
1129    results: Vec<AsyncValidationTestResult>,
1130}
1131
1132/// Async validation test result
1133#[derive(Debug, Clone, Serialize, Deserialize)]
1134pub struct AsyncValidationTestResult {
1135    /// Test name
1136    pub test_name: String,
1137    /// Export mode used
1138    pub export_mode: String,
1139    /// Validation timing
1140    pub validation_timing: String,
1141    /// Dataset size
1142    pub dataset_size: usize,
1143    /// Export time in milliseconds
1144    pub export_time_ms: u64,
1145    /// Validation time in milliseconds (if applicable)
1146    pub validation_time_ms: Option<u64>,
1147    /// Total time including validation
1148    pub total_time_ms: u64,
1149    /// Memory usage during export (bytes)
1150    pub memory_usage_bytes: usize,
1151    /// Peak memory usage (bytes)
1152    pub peak_memory_bytes: usize,
1153    /// File size generated (bytes)
1154    pub output_file_size_bytes: usize,
1155    /// Whether validation was successful
1156    pub validation_success: bool,
1157    /// Number of validation issues found
1158    pub validation_issues_count: usize,
1159    /// Whether export was successful
1160    pub export_success: bool,
1161    /// Error message if any
1162    pub error_message: Option<String>,
1163    /// Additional metrics
1164    pub additional_metrics: HashMap<String, f64>,
1165}
1166
1167/// Export mode performance comparison result
1168#[derive(Debug, Clone, Serialize, Deserialize)]
1169pub struct ModeComparisonResult {
1170    /// Dataset size tested
1171    pub dataset_size: usize,
1172    /// Fast mode result
1173    pub fast_mode_result: AsyncValidationTestResult,
1174    /// Slow mode result
1175    pub slow_mode_result: AsyncValidationTestResult,
1176    /// Speed improvement factor (fast vs slow)
1177    pub speed_improvement_factor: f64,
1178    /// Memory efficiency comparison
1179    pub memory_efficiency_comparison: f64,
1180    /// Validation quality comparison
1181    pub validation_quality_comparison: String,
1182}
1183
1184/// Async validation impact analysis
1185#[derive(Debug, Clone, Serialize, Deserialize)]
1186pub struct AsyncValidationImpactAnalysis {
1187    /// Export time without validation
1188    pub export_only_time_ms: u64,
1189    /// Export time with inline validation
1190    pub export_with_inline_validation_ms: u64,
1191    /// Export time with deferred validation
1192    pub export_with_deferred_validation_ms: u64,
1193    /// Validation overhead for inline mode
1194    pub inline_validation_overhead_percent: f64,
1195    /// Validation overhead for deferred mode
1196    pub deferred_validation_overhead_percent: f64,
1197    /// Memory usage comparison
1198    pub memory_usage_comparison: HashMap<String, usize>,
1199    /// Blocking analysis
1200    pub blocking_analysis: BlockingAnalysis,
1201}
1202
1203/// Blocking analysis for validation modes
1204#[derive(Debug, Clone, Serialize, Deserialize)]
1205pub struct BlockingAnalysis {
1206    /// Whether inline validation blocks export
1207    pub inline_blocks_export: bool,
1208    /// Whether deferred validation blocks subsequent exports
1209    pub deferred_blocks_subsequent: bool,
1210    /// Time to start subsequent export with inline validation
1211    pub inline_subsequent_start_delay_ms: u64,
1212    /// Time to start subsequent export with deferred validation
1213    pub deferred_subsequent_start_delay_ms: u64,
1214    /// Concurrent export capability
1215    pub concurrent_export_capability: String,
1216}
1217
1218impl AsyncValidationPerformanceTester {
1219    /// Create new async validation performance tester
1220    pub fn new(config: PerformanceTestConfig) -> Self {
1221        Self {
1222            config,
1223            results: Vec::new(),
1224        }
1225    }
1226
1227    /// Run comprehensive async validation performance tests
1228    pub async fn run_comprehensive_tests(
1229        &mut self,
1230        tracker: &MemoryTracker,
1231    ) -> TrackingResult<AsyncValidationPerformanceReport> {
1232        println!("šŸš€ Starting comprehensive async validation performance tests...");
1233
1234        // Test 1: Fast vs Slow mode comparison
1235        let mode_comparison_results = self.test_fast_vs_slow_mode(tracker).await?;
1236
1237        // Test 2: Async validation impact analysis
1238        let validation_impact_analysis = self.test_async_validation_impact(tracker).await?;
1239
1240        // Test 3: Deferred validation blocking test
1241        let blocking_test_results = self.test_deferred_validation_blocking(tracker).await?;
1242
1243        // Test 4: Large file memory usage test
1244        let large_file_results = self.test_large_file_memory_usage(tracker).await?;
1245
1246        // Test 5: Concurrent export capability test
1247        let concurrent_export_results = self.test_concurrent_export_capability(tracker).await?;
1248
1249        // Generate comprehensive report
1250        let report = AsyncValidationPerformanceReport {
1251            test_summary: self.generate_test_summary(),
1252            mode_comparison_results,
1253            validation_impact_analysis,
1254            blocking_test_results,
1255            large_file_results,
1256            concurrent_export_results,
1257            optimization_recommendations: self.generate_optimization_recommendations(),
1258            detailed_results: self.results.clone(),
1259        };
1260
1261        println!("āœ… Comprehensive async validation performance tests completed!");
1262        Ok(report)
1263    }
1264
1265    /// Test fast vs slow mode performance comparison
1266    async fn test_fast_vs_slow_mode(
1267        &mut self,
1268        tracker: &MemoryTracker,
1269    ) -> TrackingResult<Vec<ModeComparisonResult>> {
1270        println!("šŸ“Š Testing fast vs slow mode performance...");
1271        let mut comparison_results = Vec::new();
1272
1273        let dataset_sizes = self.config.dataset_sizes.clone();
1274        for &dataset_size in &dataset_sizes {
1275            println!("  Testing dataset size: {}", dataset_size);
1276
1277            // Generate test data
1278            self.generate_test_data(tracker, dataset_size)?;
1279
1280            // Test fast mode
1281            let fast_result = self
1282                .test_export_mode(tracker, "Fast", "Deferred", dataset_size)
1283                .await?;
1284
1285            // Test slow mode
1286            let slow_result = self
1287                .test_export_mode(tracker, "Slow", "Inline", dataset_size)
1288                .await?;
1289
1290            // Calculate comparison metrics
1291            let speed_improvement_factor = if slow_result.total_time_ms > 0 {
1292                slow_result.total_time_ms as f64 / fast_result.total_time_ms as f64
1293            } else {
1294                1.0
1295            };
1296
1297            let memory_efficiency_comparison = if slow_result.peak_memory_bytes > 0 {
1298                fast_result.peak_memory_bytes as f64 / slow_result.peak_memory_bytes as f64
1299            } else {
1300                1.0
1301            };
1302
1303            let validation_quality_comparison = if fast_result.validation_issues_count
1304                == slow_result.validation_issues_count
1305            {
1306                "Equal".to_string()
1307            } else if fast_result.validation_issues_count < slow_result.validation_issues_count {
1308                "Fast mode found fewer issues".to_string()
1309            } else {
1310                "Slow mode found fewer issues".to_string()
1311            };
1312
1313            comparison_results.push(ModeComparisonResult {
1314                dataset_size,
1315                fast_mode_result: fast_result,
1316                slow_mode_result: slow_result,
1317                speed_improvement_factor,
1318                memory_efficiency_comparison,
1319                validation_quality_comparison,
1320            });
1321        }
1322
1323        Ok(comparison_results)
1324    }
1325
1326    /// Test async validation impact on export performance
1327    async fn test_async_validation_impact(
1328        &mut self,
1329        tracker: &MemoryTracker,
1330    ) -> TrackingResult<AsyncValidationImpactAnalysis> {
1331        println!("šŸ” Testing async validation impact...");
1332
1333        let dataset_size = 10000; // Use medium dataset for this test
1334        self.generate_test_data(tracker, dataset_size)?;
1335
1336        // Test export without validation
1337        let export_only_result = self
1338            .test_export_mode(tracker, "Fast", "Disabled", dataset_size)
1339            .await?;
1340
1341        // Test export with inline validation
1342        let inline_validation_result = self
1343            .test_export_mode(tracker, "Slow", "Inline", dataset_size)
1344            .await?;
1345
1346        // Test export with deferred validation
1347        let deferred_validation_result = self
1348            .test_export_mode(tracker, "Fast", "Deferred", dataset_size)
1349            .await?;
1350
1351        // Calculate overhead percentages
1352        let inline_overhead = if export_only_result.total_time_ms > 0 {
1353            ((inline_validation_result.total_time_ms as f64
1354                - export_only_result.total_time_ms as f64)
1355                / export_only_result.total_time_ms as f64)
1356                * 100.0
1357        } else {
1358            0.0
1359        };
1360
1361        let deferred_overhead = if export_only_result.total_time_ms > 0 {
1362            ((deferred_validation_result.export_time_ms as f64
1363                - export_only_result.export_time_ms as f64)
1364                / export_only_result.export_time_ms as f64)
1365                * 100.0
1366        } else {
1367            0.0
1368        };
1369
1370        // Test blocking behavior
1371        let blocking_analysis = self.test_blocking_behavior(tracker, dataset_size).await?;
1372
1373        let mut memory_usage_comparison = HashMap::new();
1374        memory_usage_comparison.insert(
1375            "export_only".to_string(),
1376            export_only_result.memory_usage_bytes,
1377        );
1378        memory_usage_comparison.insert(
1379            "inline_validation".to_string(),
1380            inline_validation_result.memory_usage_bytes,
1381        );
1382        memory_usage_comparison.insert(
1383            "deferred_validation".to_string(),
1384            deferred_validation_result.memory_usage_bytes,
1385        );
1386
1387        Ok(AsyncValidationImpactAnalysis {
1388            export_only_time_ms: export_only_result.total_time_ms,
1389            export_with_inline_validation_ms: inline_validation_result.total_time_ms,
1390            export_with_deferred_validation_ms: deferred_validation_result.export_time_ms,
1391            inline_validation_overhead_percent: inline_overhead,
1392            deferred_validation_overhead_percent: deferred_overhead,
1393            memory_usage_comparison,
1394            blocking_analysis,
1395        })
1396    }
1397
1398    /// Test blocking behavior of different validation modes
1399    async fn test_blocking_behavior(
1400        &mut self,
1401        tracker: &MemoryTracker,
1402        dataset_size: usize,
1403    ) -> TrackingResult<BlockingAnalysis> {
1404        println!("🚦 Testing validation blocking behavior...");
1405
1406        // Test inline validation blocking
1407        let inline_start = Instant::now();
1408        let _inline_result = self
1409            .test_export_mode(tracker, "Slow", "Inline", dataset_size)
1410            .await?;
1411        let inline_subsequent_start = Instant::now();
1412        let inline_delay = inline_subsequent_start
1413            .duration_since(inline_start)
1414            .as_millis() as u64;
1415
1416        // Test deferred validation blocking
1417        let deferred_start = Instant::now();
1418        let _deferred_result = self
1419            .test_export_mode(tracker, "Fast", "Deferred", dataset_size)
1420            .await?;
1421        let deferred_subsequent_start = Instant::now();
1422        let deferred_delay = deferred_subsequent_start
1423            .duration_since(deferred_start)
1424            .as_millis() as u64;
1425
1426        Ok(BlockingAnalysis {
1427            inline_blocks_export: true,        // Inline validation always blocks
1428            deferred_blocks_subsequent: false, // Deferred validation should not block
1429            inline_subsequent_start_delay_ms: inline_delay,
1430            deferred_subsequent_start_delay_ms: deferred_delay,
1431            concurrent_export_capability: if deferred_delay < inline_delay {
1432                "Deferred validation enables better concurrency".to_string()
1433            } else {
1434                "No significant concurrency improvement".to_string()
1435            },
1436        })
1437    }
1438
1439    /// Test deferred validation blocking behavior
1440    async fn test_deferred_validation_blocking(
1441        &mut self,
1442        tracker: &MemoryTracker,
1443    ) -> TrackingResult<Vec<AsyncValidationTestResult>> {
1444        println!("šŸ”„ Testing deferred validation blocking behavior...");
1445        let mut results = Vec::new();
1446
1447        for &dataset_size in &[1000, 5000, 10000] {
1448            // Test multiple concurrent exports with deferred validation
1449            let concurrent_start = Instant::now();
1450
1451            let mut concurrent_results = Vec::new();
1452            for _i in 0..3 {
1453                let result = self
1454                    .test_export_mode(tracker, "Fast", "Deferred", dataset_size)
1455                    .await?;
1456                concurrent_results.push(result);
1457            }
1458
1459            let concurrent_total_time = concurrent_start.elapsed().as_millis() as u64;
1460
1461            // Create summary result
1462            let avg_export_time = concurrent_results
1463                .iter()
1464                .map(|r| r.export_time_ms)
1465                .sum::<u64>()
1466                / concurrent_results.len() as u64;
1467
1468            let summary_result = AsyncValidationTestResult {
1469                test_name: format!("Concurrent_Deferred_Validation_{}", dataset_size),
1470                export_mode: "Fast".to_string(),
1471                validation_timing: "Deferred".to_string(),
1472                dataset_size,
1473                export_time_ms: avg_export_time,
1474                validation_time_ms: None,
1475                total_time_ms: concurrent_total_time,
1476                memory_usage_bytes: concurrent_results
1477                    .iter()
1478                    .map(|r| r.memory_usage_bytes)
1479                    .max()
1480                    .unwrap_or(0),
1481                peak_memory_bytes: concurrent_results
1482                    .iter()
1483                    .map(|r| r.peak_memory_bytes)
1484                    .max()
1485                    .unwrap_or(0),
1486                output_file_size_bytes: concurrent_results
1487                    .iter()
1488                    .map(|r| r.output_file_size_bytes)
1489                    .sum(),
1490                validation_success: concurrent_results.iter().all(|r| r.validation_success),
1491                validation_issues_count: concurrent_results
1492                    .iter()
1493                    .map(|r| r.validation_issues_count)
1494                    .sum(),
1495                export_success: concurrent_results.iter().all(|r| r.export_success),
1496                error_message: None,
1497                additional_metrics: HashMap::new(),
1498            };
1499
1500            results.push(summary_result);
1501        }
1502
1503        Ok(results)
1504    }
1505
1506    /// Test large file memory usage scenarios
1507    async fn test_large_file_memory_usage(
1508        &mut self,
1509        tracker: &MemoryTracker,
1510    ) -> TrackingResult<Vec<AsyncValidationTestResult>> {
1511        println!("šŸ’¾ Testing large file memory usage...");
1512        let mut results = Vec::new();
1513
1514        // Test with progressively larger datasets
1515        let large_dataset_sizes = vec![20000, 50000, 100000];
1516
1517        for &dataset_size in &large_dataset_sizes {
1518            println!("  Testing large dataset size: {}", dataset_size);
1519
1520            // Test fast mode with large dataset
1521            let fast_large_result = self
1522                .test_export_mode(tracker, "Fast", "Deferred", dataset_size)
1523                .await?;
1524
1525            // Test slow mode with large dataset (if memory allows)
1526            let slow_large_result = if dataset_size <= 50000 {
1527                // Limit slow mode for very large datasets
1528                Some(
1529                    self.test_export_mode(tracker, "Slow", "Inline", dataset_size)
1530                        .await?,
1531                )
1532            } else {
1533                None
1534            };
1535
1536            results.push(fast_large_result);
1537            if let Some(slow_result) = slow_large_result {
1538                results.push(slow_result);
1539            }
1540        }
1541
1542        Ok(results)
1543    }
1544
1545    /// Test concurrent export capability
1546    async fn test_concurrent_export_capability(
1547        &mut self,
1548        tracker: &MemoryTracker,
1549    ) -> TrackingResult<Vec<AsyncValidationTestResult>> {
1550        println!("šŸ”€ Testing concurrent export capability...");
1551        let mut results = Vec::new();
1552
1553        let dataset_size = 5000;
1554
1555        // Test sequential exports
1556        let sequential_start = Instant::now();
1557        for _i in 0..3 {
1558            let result = self
1559                .test_export_mode(tracker, "Fast", "Deferred", dataset_size)
1560                .await?;
1561            results.push(result);
1562        }
1563        let sequential_time = sequential_start.elapsed().as_millis() as u64;
1564
1565        // Create summary for concurrent capability
1566        let concurrent_summary = AsyncValidationTestResult {
1567            test_name: "Concurrent_Export_Capability".to_string(),
1568            export_mode: "Fast".to_string(),
1569            validation_timing: "Deferred".to_string(),
1570            dataset_size,
1571            export_time_ms: sequential_time / 3, // Average per export
1572            validation_time_ms: None,
1573            total_time_ms: sequential_time,
1574            memory_usage_bytes: results
1575                .iter()
1576                .map(|r| r.memory_usage_bytes)
1577                .max()
1578                .unwrap_or(0),
1579            peak_memory_bytes: results
1580                .iter()
1581                .map(|r| r.peak_memory_bytes)
1582                .max()
1583                .unwrap_or(0),
1584            output_file_size_bytes: results.iter().map(|r| r.output_file_size_bytes).sum(),
1585            validation_success: results.iter().all(|r| r.validation_success),
1586            validation_issues_count: results.iter().map(|r| r.validation_issues_count).sum(),
1587            export_success: results.iter().all(|r| r.export_success),
1588            error_message: None,
1589            additional_metrics: {
1590                let mut metrics = HashMap::new();
1591                metrics.insert("concurrent_exports".to_string(), 3.0);
1592                metrics.insert(
1593                    "total_concurrent_time_ms".to_string(),
1594                    sequential_time as f64,
1595                );
1596                metrics
1597            },
1598        };
1599
1600        results.push(concurrent_summary);
1601        Ok(results)
1602    }
1603
1604    /// Test a specific export mode and validation timing
1605    async fn test_export_mode(
1606        &mut self,
1607        tracker: &MemoryTracker,
1608        mode: &str,
1609        validation_timing: &str,
1610        dataset_size: usize,
1611    ) -> TrackingResult<AsyncValidationTestResult> {
1612        // use crate::export::quality_validator::{ExportMode, ValidationTiming}; // Removed
1613
1614        use crate::export::quality_validator::{ExportMode, ValidationTiming};
1615
1616        let _export_mode = match mode {
1617            "Fast" => ExportMode::Fast,
1618            "Slow" => ExportMode::Slow,
1619            "Auto" => ExportMode::Auto,
1620            _ => ExportMode::Fast,
1621        };
1622
1623        let _validation_timing_enum = match validation_timing {
1624            "Inline" => ValidationTiming::Inline,
1625            "Deferred" => ValidationTiming::Deferred,
1626            "Disabled" => ValidationTiming::Disabled,
1627            _ => ValidationTiming::Deferred,
1628        };
1629
1630        let test_name = format!(
1631            "{}_{}_{}_{}",
1632            mode,
1633            validation_timing,
1634            dataset_size,
1635            chrono::Utc::now().timestamp()
1636        );
1637        let output_path = format!("test_output_{}", test_name);
1638
1639        // Measure memory before export
1640        let memory_before = self.get_current_memory_usage();
1641
1642        // Perform export with timing
1643        let export_start = Instant::now();
1644        let export_result = tracker.export_to_json(&output_path);
1645        let export_time = export_start.elapsed().as_millis() as u64;
1646
1647        // Measure memory after export
1648        let memory_after = self.get_current_memory_usage();
1649        let memory_usage = memory_after.saturating_sub(memory_before);
1650
1651        // Get file size if export was successful
1652        let output_file_size = if export_result.is_ok() {
1653            std::fs::metadata(format!("{}.json", output_path))
1654                .map(|m| m.len() as usize)
1655                .unwrap_or(0)
1656        } else {
1657            0
1658        };
1659
1660        // Create test result
1661        let result = AsyncValidationTestResult {
1662            test_name: test_name.clone(),
1663            export_mode: mode.to_string(),
1664            validation_timing: validation_timing.to_string(),
1665            dataset_size,
1666            export_time_ms: export_time,
1667            validation_time_ms: None, // TODO: Implement validation timing measurement
1668            total_time_ms: export_time,
1669            memory_usage_bytes: memory_usage,
1670            peak_memory_bytes: memory_usage, // Simplified for now
1671            output_file_size_bytes: output_file_size,
1672            validation_success: true, // TODO: Implement validation success detection
1673            validation_issues_count: 0, // TODO: Implement validation issue counting
1674            export_success: export_result.is_ok(),
1675            error_message: export_result.err().map(|e| e.to_string()),
1676            additional_metrics: HashMap::new(),
1677        };
1678
1679        self.results.push(result.clone());
1680
1681        // Cleanup test files
1682        let _ = std::fs::remove_file(format!("{}.json", output_path));
1683
1684        Ok(result)
1685    }
1686
1687    /// Generate test data for the tracker
1688    fn generate_test_data(&self, _tracker: &MemoryTracker, size: usize) -> TrackingResult<()> {
1689        // This is a simplified test data generation
1690        // In a real implementation, you would populate the tracker with test allocations
1691        println!("  Generating test data of size: {}", size);
1692        Ok(())
1693    }
1694
1695    /// Get current memory usage (simplified implementation)
1696    fn get_current_memory_usage(&self) -> usize {
1697        // This is a placeholder - in a real implementation you would measure actual memory usage
1698        use std::alloc::{GlobalAlloc, Layout, System};
1699
1700        // Simple approximation using a small allocation to trigger memory measurement
1701        let layout = Layout::new::<[u8; 1024]>();
1702        unsafe {
1703            let ptr = System.alloc(layout);
1704            if !ptr.is_null() {
1705                System.dealloc(ptr, layout);
1706            }
1707        }
1708
1709        // Return a placeholder value - real implementation would use system APIs
1710        1024 * 1024 // 1MB placeholder
1711    }
1712
1713    /// Generate test summary
1714    fn generate_test_summary(&self) -> AsyncValidationTestSummary {
1715        let total_tests = self.results.len();
1716        let successful_tests = self.results.iter().filter(|r| r.export_success).count();
1717        let failed_tests = total_tests - successful_tests;
1718
1719        let avg_export_time = if !self.results.is_empty() {
1720            self.results.iter().map(|r| r.export_time_ms).sum::<u64>() / self.results.len() as u64
1721        } else {
1722            0
1723        };
1724
1725        let total_test_time = self.results.iter().map(|r| r.total_time_ms).sum::<u64>();
1726
1727        AsyncValidationTestSummary {
1728            total_tests,
1729            successful_tests,
1730            failed_tests,
1731            avg_export_time_ms: avg_export_time,
1732            total_test_time_ms: total_test_time,
1733        }
1734    }
1735
1736    /// Generate optimization recommendations based on test results
1737    fn generate_optimization_recommendations(&self) -> Vec<OptimizationRecommendation> {
1738        let mut recommendations = Vec::new();
1739
1740        // Analyze fast vs slow mode performance
1741        let fast_results: Vec<_> = self
1742            .results
1743            .iter()
1744            .filter(|r| r.export_mode == "Fast")
1745            .collect();
1746        let slow_results: Vec<_> = self
1747            .results
1748            .iter()
1749            .filter(|r| r.export_mode == "Slow")
1750            .collect();
1751
1752        if !fast_results.is_empty() && !slow_results.is_empty() {
1753            let avg_fast_time = fast_results.iter().map(|r| r.export_time_ms).sum::<u64>()
1754                / fast_results.len() as u64;
1755            let avg_slow_time = slow_results.iter().map(|r| r.export_time_ms).sum::<u64>()
1756                / slow_results.len() as u64;
1757
1758            if avg_fast_time < avg_slow_time {
1759                let improvement_factor = avg_slow_time as f64 / avg_fast_time as f64;
1760                recommendations.push(OptimizationRecommendation {
1761                    category: "Export Mode".to_string(),
1762                    recommendation: "Use Fast mode for better performance".to_string(),
1763                    impact: format!("{:.1}x faster than Slow mode", improvement_factor),
1764                    reason: "Fast mode shows significantly better performance in tests".to_string(),
1765                });
1766            }
1767        }
1768
1769        // Analyze validation timing impact
1770        let deferred_results: Vec<_> = self
1771            .results
1772            .iter()
1773            .filter(|r| r.validation_timing == "Deferred")
1774            .collect();
1775        let inline_results: Vec<_> = self
1776            .results
1777            .iter()
1778            .filter(|r| r.validation_timing == "Inline")
1779            .collect();
1780
1781        if !deferred_results.is_empty() && !inline_results.is_empty() {
1782            recommendations.push(OptimizationRecommendation {
1783                category: "Validation Timing".to_string(),
1784                recommendation: "Use Deferred validation for non-blocking exports".to_string(),
1785                impact: "Enables concurrent operations".to_string(),
1786                reason: "Deferred validation doesn't block the export process".to_string(),
1787            });
1788        }
1789
1790        // Memory usage recommendations
1791        let high_memory_results: Vec<_> = self
1792            .results
1793            .iter()
1794            .filter(|r| r.memory_usage_bytes > 50 * 1024 * 1024) // > 50MB
1795            .collect();
1796
1797        if !high_memory_results.is_empty() {
1798            recommendations.push(OptimizationRecommendation {
1799                category: "Memory Usage".to_string(),
1800                recommendation: "Consider using streaming validation for large datasets"
1801                    .to_string(),
1802                impact: "Reduces memory footprint".to_string(),
1803                reason: "High memory usage detected in large dataset tests".to_string(),
1804            });
1805        }
1806
1807        recommendations
1808    }
1809}
1810
1811/// Async validation performance report
1812#[derive(Debug, Clone, Serialize, Deserialize)]
1813pub struct AsyncValidationPerformanceReport {
1814    /// Test summary
1815    pub test_summary: AsyncValidationTestSummary,
1816    /// Mode comparison results
1817    pub mode_comparison_results: Vec<ModeComparisonResult>,
1818    /// Validation impact analysis
1819    pub validation_impact_analysis: AsyncValidationImpactAnalysis,
1820    /// Blocking test results
1821    pub blocking_test_results: Vec<AsyncValidationTestResult>,
1822    /// Large file test results
1823    pub large_file_results: Vec<AsyncValidationTestResult>,
1824    /// Concurrent export test results
1825    pub concurrent_export_results: Vec<AsyncValidationTestResult>,
1826    /// Optimization recommendations
1827    pub optimization_recommendations: Vec<OptimizationRecommendation>,
1828    /// Detailed test results
1829    pub detailed_results: Vec<AsyncValidationTestResult>,
1830}
1831
1832/// Async validation test summary
1833#[derive(Debug, Clone, Serialize, Deserialize)]
1834pub struct AsyncValidationTestSummary {
1835    /// Total number of tests run
1836    pub total_tests: usize,
1837    /// Number of successful tests
1838    pub successful_tests: usize,
1839    /// Number of failed tests
1840    pub failed_tests: usize,
1841    /// Average export time across all tests
1842    pub avg_export_time_ms: u64,
1843    /// Total time spent on all tests
1844    pub total_test_time_ms: u64,
1845}
1846
1847impl AsyncValidationPerformanceReport {
1848    /// Print comprehensive performance report
1849    pub fn print_comprehensive_report(&self) {
1850        println!("\nšŸš€ Async Validation Performance Report");
1851        println!("=====================================");
1852
1853        // Print test summary
1854        println!("\nšŸ“Š Test Summary:");
1855        println!("   Total tests: {}", self.test_summary.total_tests);
1856        println!(
1857            "   Successful tests: {} ({:.1}%)",
1858            self.test_summary.successful_tests,
1859            (self.test_summary.successful_tests as f64 / self.test_summary.total_tests as f64)
1860                * 100.0
1861        );
1862        println!("   Failed tests: {}", self.test_summary.failed_tests);
1863        println!(
1864            "   Average export time: {}ms",
1865            self.test_summary.avg_export_time_ms
1866        );
1867        println!(
1868            "   Total test time: {}ms",
1869            self.test_summary.total_test_time_ms
1870        );
1871
1872        // Print mode comparison results
1873        println!("\n⚔ Fast vs Slow Mode Comparison:");
1874        for comparison in &self.mode_comparison_results {
1875            println!("   Dataset size: {}", comparison.dataset_size);
1876            println!(
1877                "     Fast mode: {}ms",
1878                comparison.fast_mode_result.total_time_ms
1879            );
1880            println!(
1881                "     Slow mode: {}ms",
1882                comparison.slow_mode_result.total_time_ms
1883            );
1884            println!(
1885                "     Speed improvement: {:.1}x",
1886                comparison.speed_improvement_factor
1887            );
1888            println!(
1889                "     Memory efficiency: {:.2}",
1890                comparison.memory_efficiency_comparison
1891            );
1892            println!(
1893                "     Validation quality: {}",
1894                comparison.validation_quality_comparison
1895            );
1896            println!();
1897        }
1898
1899        // Print validation impact analysis
1900        println!("šŸ” Validation Impact Analysis:");
1901        let impact = &self.validation_impact_analysis;
1902        println!("   Export only: {}ms", impact.export_only_time_ms);
1903        println!(
1904            "   With inline validation: {}ms (+{:.1}%)",
1905            impact.export_with_inline_validation_ms, impact.inline_validation_overhead_percent
1906        );
1907        println!(
1908            "   With deferred validation: {}ms (+{:.1}%)",
1909            impact.export_with_deferred_validation_ms, impact.deferred_validation_overhead_percent
1910        );
1911
1912        // Print blocking analysis
1913        println!("\n🚦 Blocking Analysis:");
1914        let blocking = &impact.blocking_analysis;
1915        println!(
1916            "   Inline validation blocks export: {}",
1917            blocking.inline_blocks_export
1918        );
1919        println!(
1920            "   Deferred validation blocks subsequent: {}",
1921            blocking.deferred_blocks_subsequent
1922        );
1923        println!(
1924            "   Concurrent capability: {}",
1925            blocking.concurrent_export_capability
1926        );
1927
1928        // Print optimization recommendations
1929        println!("\nšŸ’” Optimization Recommendations:");
1930        for (i, rec) in self.optimization_recommendations.iter().enumerate() {
1931            println!("   {}. {} - {}", i + 1, rec.category, rec.recommendation);
1932            println!("      Impact: {}", rec.impact);
1933            println!("      Reason: {}", rec.reason);
1934            println!();
1935        }
1936    }
1937
1938    /// Save report to JSON file
1939    pub fn save_to_file<P: AsRef<std::path::Path>>(&self, path: P) -> TrackingResult<()> {
1940        let json_data = serde_json::to_string_pretty(self).map_err(|e| {
1941            crate::core::types::TrackingError::SerializationError(format!(
1942                "Failed to serialize report: {}",
1943                e
1944            ))
1945        })?;
1946
1947        std::fs::write(path, json_data).map_err(|e| {
1948            crate::core::types::TrackingError::IoError(format!(
1949                "Failed to write report file: {}",
1950                e
1951            ))
1952        })?;
1953
1954        Ok(())
1955    }
1956}