#![ cfg( feature = "enabled" ) ]
#![ cfg( feature = "markdown_reports" ) ]
#![ allow( clippy ::uninlined_format_args ) ]
#![ allow( clippy ::format_push_string ) ]
#![ allow( clippy ::cast_lossless ) ]
#![ allow( clippy ::cast_possible_truncation ) ]
#![ allow( clippy ::cast_precision_loss ) ]
#![ allow( clippy ::std_instead_of_core ) ]
#![ allow( clippy ::needless_raw_string_hashes ) ]
#![ allow( clippy ::too_many_lines ) ]
use benchkit ::prelude :: *;
use std ::collections ::HashMap;
use std ::time :: { Duration, SystemTime };
fn create_current_results() -> HashMap< String, BenchmarkResult >
{
let mut results = HashMap ::new();
let fast_sort_times = vec![
Duration ::from_micros( 85 ), Duration ::from_micros( 88 ), Duration ::from_micros( 82 ),
Duration ::from_micros( 87 ), Duration ::from_micros( 84 ), Duration ::from_micros( 86 ),
Duration ::from_micros( 89 ), Duration ::from_micros( 81 ), Duration ::from_micros( 88 ),
Duration ::from_micros( 85 ), Duration ::from_micros( 87 ), Duration ::from_micros( 83 ),
Duration ::from_micros( 86 ), Duration ::from_micros( 84 ), Duration ::from_micros( 88 )
];
results.insert( "fast_sort".to_string(), BenchmarkResult ::new( "fast_sort", fast_sort_times ) );
let hash_times = vec![
Duration ::from_nanos( 150 ), Duration ::from_nanos( 152 ), Duration ::from_nanos( 148 ),
Duration ::from_nanos( 151 ), Duration ::from_nanos( 149 ), Duration ::from_nanos( 150 ),
Duration ::from_nanos( 153 ), Duration ::from_nanos( 147 ), Duration ::from_nanos( 151 ),
Duration ::from_nanos( 150 ), Duration ::from_nanos( 152 ), Duration ::from_nanos( 149 )
];
results.insert( "hash_function".to_string(), BenchmarkResult ::new( "hash_function", hash_times ) );
let allocator_times = vec![
Duration ::from_micros( 320 ), Duration ::from_micros( 335 ), Duration ::from_micros( 315 ),
Duration ::from_micros( 330 ), Duration ::from_micros( 325 ), Duration ::from_micros( 340 ),
Duration ::from_micros( 310 ), Duration ::from_micros( 345 ), Duration ::from_micros( 318 ),
Duration ::from_micros( 332 ), Duration ::from_micros( 327 ), Duration ::from_micros( 338 )
];
results.insert( "memory_allocator".to_string(), BenchmarkResult ::new( "memory_allocator", allocator_times ) );
results
}
fn create_baseline_historical_data() -> HistoricalResults
{
let mut baseline_data = HashMap ::new();
let baseline_fast_sort = vec![
Duration ::from_micros( 110 ), Duration ::from_micros( 115 ), Duration ::from_micros( 108 ),
Duration ::from_micros( 112 ), Duration ::from_micros( 117 ), Duration ::from_micros( 111 ),
Duration ::from_micros( 114 ), Duration ::from_micros( 107 ), Duration ::from_micros( 113 ),
Duration ::from_micros( 109 ), Duration ::from_micros( 116 ), Duration ::from_micros( 106 )
];
baseline_data.insert( "fast_sort".to_string(), BenchmarkResult ::new( "fast_sort", baseline_fast_sort ) );
let baseline_hash = vec![
Duration ::from_nanos( 148 ), Duration ::from_nanos( 152 ), Duration ::from_nanos( 146 ),
Duration ::from_nanos( 150 ), Duration ::from_nanos( 154 ), Duration ::from_nanos( 147 ),
Duration ::from_nanos( 151 ), Duration ::from_nanos( 149 ), Duration ::from_nanos( 153 ),
Duration ::from_nanos( 148 ), Duration ::from_nanos( 152 ), Duration ::from_nanos( 150 )
];
baseline_data.insert( "hash_function".to_string(), BenchmarkResult ::new( "hash_function", baseline_hash ) );
let baseline_allocator = vec![
Duration ::from_micros( 280 ), Duration ::from_micros( 285 ), Duration ::from_micros( 275 ),
Duration ::from_micros( 282 ), Duration ::from_micros( 287 ), Duration ::from_micros( 278 ),
Duration ::from_micros( 284 ), Duration ::from_micros( 276 ), Duration ::from_micros( 283 ),
Duration ::from_micros( 279 ), Duration ::from_micros( 286 ), Duration ::from_micros( 277 )
];
baseline_data.insert( "memory_allocator".to_string(), BenchmarkResult ::new( "memory_allocator", baseline_allocator ) );
HistoricalResults ::new().with_baseline( baseline_data )
}
fn create_rolling_average_historical_data() -> HistoricalResults
{
let mut historical_runs = Vec ::new();
let mut run1_results = HashMap ::new();
let run1_fast_sort = vec![ Duration ::from_micros( 120 ), Duration ::from_micros( 125 ), Duration ::from_micros( 118 ) ];
let run1_hash = vec![ Duration ::from_nanos( 155 ), Duration ::from_nanos( 160 ), Duration ::from_nanos( 150 ) ];
let run1_allocator = vec![ Duration ::from_micros( 290 ), Duration ::from_micros( 295 ), Duration ::from_micros( 285 ) ];
run1_results.insert( "fast_sort".to_string(), BenchmarkResult ::new( "fast_sort", run1_fast_sort ) );
run1_results.insert( "hash_function".to_string(), BenchmarkResult ::new( "hash_function", run1_hash ) );
run1_results.insert( "memory_allocator".to_string(), BenchmarkResult ::new( "memory_allocator", run1_allocator ) );
historical_runs.push( TimestampedResults ::new(
SystemTime ::now() - Duration ::from_secs( 1_209_600 ), run1_results
) );
let mut run2_results = HashMap ::new();
let run2_fast_sort = vec![ Duration ::from_micros( 100 ), Duration ::from_micros( 105 ), Duration ::from_micros( 98 ) ];
let run2_hash = vec![ Duration ::from_nanos( 150 ), Duration ::from_nanos( 155 ), Duration ::from_nanos( 145 ) ];
let run2_allocator = vec![ Duration ::from_micros( 285 ), Duration ::from_micros( 290 ), Duration ::from_micros( 280 ) ];
run2_results.insert( "fast_sort".to_string(), BenchmarkResult ::new( "fast_sort", run2_fast_sort ) );
run2_results.insert( "hash_function".to_string(), BenchmarkResult ::new( "hash_function", run2_hash ) );
run2_results.insert( "memory_allocator".to_string(), BenchmarkResult ::new( "memory_allocator", run2_allocator ) );
historical_runs.push( TimestampedResults ::new(
SystemTime ::now() - Duration ::from_secs( 604_800 ), run2_results
) );
let mut run3_results = HashMap ::new();
let run3_fast_sort = vec![ Duration ::from_micros( 95 ), Duration ::from_micros( 98 ), Duration ::from_micros( 92 ) ];
let run3_hash = vec![ Duration ::from_nanos( 148 ), Duration ::from_nanos( 153 ), Duration ::from_nanos( 147 ) ];
let run3_allocator = vec![ Duration ::from_micros( 305 ), Duration ::from_micros( 310 ), Duration ::from_micros( 300 ) ];
run3_results.insert( "fast_sort".to_string(), BenchmarkResult ::new( "fast_sort", run3_fast_sort ) );
run3_results.insert( "hash_function".to_string(), BenchmarkResult ::new( "hash_function", run3_hash ) );
run3_results.insert( "memory_allocator".to_string(), BenchmarkResult ::new( "memory_allocator", run3_allocator ) );
historical_runs.push( TimestampedResults ::new(
SystemTime ::now() - Duration ::from_secs( 259_200 ), run3_results
) );
HistoricalResults ::new().with_historical_runs( historical_runs )
}
fn create_previous_run_historical_data() -> HistoricalResults
{
let mut previous_results = HashMap ::new();
let prev_fast_sort = vec![ Duration ::from_micros( 90 ), Duration ::from_micros( 95 ), Duration ::from_micros( 88 ) ];
let prev_hash = vec![ Duration ::from_nanos( 149 ), Duration ::from_nanos( 154 ), Duration ::from_nanos( 146 ) ];
let prev_allocator = vec![ Duration ::from_micros( 295 ), Duration ::from_micros( 300 ), Duration ::from_micros( 290 ) ];
previous_results.insert( "fast_sort".to_string(), BenchmarkResult ::new( "fast_sort", prev_fast_sort ) );
previous_results.insert( "hash_function".to_string(), BenchmarkResult ::new( "hash_function", prev_hash ) );
previous_results.insert( "memory_allocator".to_string(), BenchmarkResult ::new( "memory_allocator", prev_allocator ) );
let previous_run = TimestampedResults ::new(
SystemTime ::now() - Duration ::from_secs( 86_400 ), previous_results
);
HistoricalResults ::new().with_previous_run( previous_run )
}
fn demonstrate_fixed_baseline_strategy()
{
println!( "🎯 FIXED BASELINE STRATEGY DEMONSTRATION" );
println!( "=========================================" );
println!( "Comparing current performance against a fixed baseline measurement." );
println!( "Use case: Long-term performance tracking against a stable reference point.\n" );
let current_results = create_current_results();
let historical = create_baseline_historical_data();
let analyzer = RegressionAnalyzer ::new()
.with_baseline_strategy( BaselineStrategy ::FixedBaseline )
.with_significance_threshold( 0.01 ) .with_trend_window( 5 );
let regression_report = analyzer.analyze( ¤t_results, &historical );
println!( "📊 REGRESSION ANALYSIS RESULTS: " );
println!( "--------------------------------" );
for operation in [ "fast_sort", "hash_function", "memory_allocator" ]
{
if let Some( trend ) = regression_report.get_trend_for( operation )
{
let significance = if regression_report.is_statistically_significant( operation )
{
"✓ Statistically Significant"
}
else
{
"- Not Significant"
};
let trend_emoji = match trend
{
PerformanceTrend ::Improving => "🟢 IMPROVING",
PerformanceTrend ::Degrading => "🔴 DEGRADING",
PerformanceTrend ::Stable => "🟡 STABLE",
};
println!( " {} - {} ({})", operation, trend_emoji, significance );
}
}
let markdown_report = regression_report.format_markdown();
println!( "\n📝 GENERATED MARKDOWN REPORT: " );
println!( "------------------------------" );
println!( "{}", markdown_report );
println!( "\n" );
}
fn demonstrate_rolling_average_strategy()
{
println!( "📈 ROLLING AVERAGE STRATEGY DEMONSTRATION" );
println!( "==========================================" );
println!( "Comparing current performance against rolling average of recent runs." );
println!( "Use case: Detecting gradual performance trends over time.\n" );
let current_results = create_current_results();
let historical = create_rolling_average_historical_data();
let analyzer = RegressionAnalyzer ::new()
.with_baseline_strategy( BaselineStrategy ::RollingAverage )
.with_significance_threshold( 0.05 ) .with_trend_window( 3 );
let regression_report = analyzer.analyze( ¤t_results, &historical );
println!( "📊 TREND ANALYSIS RESULTS: " );
println!( "--------------------------" );
for operation in [ "fast_sort", "hash_function", "memory_allocator" ]
{
if regression_report.has_historical_data( operation )
{
let trend = regression_report.get_trend_for( operation ).unwrap();
let significance = regression_report.is_statistically_significant( operation );
println!( " 🔍 {} Analysis: ", operation );
println!( " Trend: {:?}", trend );
println!( " Statistical Significance: {}", if significance { "Yes" } else { "No" } );
println!( " Historical Data Points: Available" );
println!();
}
}
if regression_report.has_significant_changes()
{
println!( "⚠️ ALERT: Significant performance changes detected!" );
}
else
{
println!( "✅ STATUS: Performance within normal variation ranges" );
}
println!( "\n" );
}
fn demonstrate_previous_run_strategy()
{
println!( "⏮️ PREVIOUS RUN STRATEGY DEMONSTRATION" );
println!( "=======================================" );
println!( "Comparing current performance against the immediate previous run." );
println!( "Use case: Detecting immediate impact of recent changes.\n" );
let current_results = create_current_results();
let historical = create_previous_run_historical_data();
let analyzer = RegressionAnalyzer ::new()
.with_baseline_strategy( BaselineStrategy ::PreviousRun )
.with_significance_threshold( 0.10 ) .with_trend_window( 2 );
let regression_report = analyzer.analyze( ¤t_results, &historical );
println!( "📊 IMMEDIATE CHANGE ANALYSIS: " );
println!( "-----------------------------" );
if regression_report.has_previous_run_data()
{
for operation in [ "fast_sort", "hash_function", "memory_allocator" ]
{
if let Some( trend ) = regression_report.get_trend_for( operation )
{
let change_indicator = match trend
{
PerformanceTrend ::Improving => "↗️ Performance improved since last run",
PerformanceTrend ::Degrading => "↘️ Performance degraded since last run",
PerformanceTrend ::Stable => "➡️ Performance stable since last run",
};
println!( " {} - {}", operation, change_indicator );
}
}
}
else
{
println!( " ❌ No previous run data available for comparison" );
}
println!( "\n" );
}
fn demonstrate_template_integration()
{
println!( "📋 PERFORMANCE REPORT TEMPLATE INTEGRATION" );
println!( "===========================================" );
println!( "Demonstrating full integration with PerformanceReport templates." );
println!( "Use case: Automated performance documentation with regression insights.\n" );
let current_results = create_current_results();
let historical = create_rolling_average_historical_data();
let template = PerformanceReport ::new()
.title( "Algorithm Performance Analysis with Regression Detection" )
.add_context( "Comprehensive analysis after code optimization and system updates" )
.include_statistical_analysis( true )
.include_regression_analysis( true )
.with_historical_data( historical )
.add_custom_section( CustomSection ::new(
"Optimization Impact Analysis",
r#"### Key Changes Made
- **fast_sort** : Applied cache-friendly memory access patterns
- **hash_function** : No changes (stable baseline)
- **memory_allocator** : System update may have introduced overhead
### Expected Outcomes
- fast_sort should show significant improvement
- hash_function should remain stable
- memory_allocator performance needs investigation"#
) );
match template.generate( ¤t_results )
{
Ok( report ) =>
{
println!( "✅ GENERATED COMPREHENSIVE PERFORMANCE REPORT: " );
println!( "----------------------------------------------" );
let lines: Vec< &str > = report.lines().collect();
let mut in_regression_section = false;
let mut regression_lines = Vec ::new();
for line in lines
{
if line.contains( "## Regression Analysis" )
{
in_regression_section = true;
}
else if line.starts_with( "## " ) && in_regression_section
{
break;
}
if in_regression_section
{
regression_lines.push( line );
}
}
if !regression_lines.is_empty()
{
println!( "📊 REGRESSION ANALYSIS SECTION: " );
for line in regression_lines.iter().take( 15 ) {
println!( "{}", line );
}
if regression_lines.len() > 15
{
println!( "... ({} more lines)", regression_lines.len() - 15 );
}
}
let report_size = report.len();
let line_count = report.matches( '\n' ).count();
println!( "\n📈 REPORT STATISTICS: " );
println!( " Size: {} characters", report_size );
println!( " Lines: {} lines", line_count );
println!( " Includes: Executive Summary, Performance Results, Statistical Analysis, Regression Analysis, Custom Sections" );
},
Err( e ) =>
{
println!( "❌ ERROR generating report: {}", e );
}
}
println!( "\n" );
}
fn demonstrate_significance_tuning()
{
println!( "🎛️ STATISTICAL SIGNIFICANCE TUNING" );
println!( "===================================" );
println!( "Demonstrating how different significance thresholds affect regression detection." );
println!( "Use case: Calibrating sensitivity for different environments.\n" );
let current_results = create_current_results();
let historical = create_baseline_historical_data();
let thresholds = vec![ 0.01, 0.05, 0.10, 0.20 ];
for &threshold in &thresholds
{
println!( "📊 ANALYSIS WITH {}% SIGNIFICANCE THRESHOLD: ", ( threshold * 100.0 ) as i32 );
let analyzer = RegressionAnalyzer ::new()
.with_baseline_strategy( BaselineStrategy ::FixedBaseline )
.with_significance_threshold( threshold );
let regression_report = analyzer.analyze( ¤t_results, &historical );
let mut significant_count = 0;
let operations = [ "fast_sort", "hash_function", "memory_allocator" ];
for operation in &operations
{
if regression_report.is_statistically_significant( operation )
{
significant_count += 1;
}
}
println!( " Significant changes detected: {}/{}", significant_count, operations.len() );
if regression_report.is_statistically_significant( "fast_sort" )
{
println!( " fast_sort: ✓ Significant improvement detected" );
}
else
{
println!( " fast_sort: - Improvement not statistically significant at this level" );
}
println!();
}
println!( "💡 TUNING GUIDANCE: " );
println!( " - Strict thresholds (1-5%) : Production environments, critical systems" );
println!( " - Moderate thresholds (5-10%) : Development, performance monitoring" );
println!( " - Lenient thresholds (10-20%) : Early development, noisy environments\n" );
}
fn main()
{
println!( "🚀 BENCHKIT REGRESSION ANALYSIS COMPREHENSIVE DEMO" );
println!( "====================================================" );
println!( "This example demonstrates every aspect of the new regression analysis system: \n" );
demonstrate_fixed_baseline_strategy();
demonstrate_rolling_average_strategy();
demonstrate_previous_run_strategy();
demonstrate_template_integration();
demonstrate_significance_tuning();
println!( "✨ SUMMARY OF DEMONSTRATED FEATURES: " );
println!( "=====================================" );
println!( "✅ All three baseline strategies (Fixed, Rolling Average, Previous Run)" );
println!( "✅ Performance trend detection (Improving, Degrading, Stable)" );
println!( "✅ Statistical significance testing with configurable thresholds" );
println!( "✅ Historical data management (baseline, runs, previous run)" );
println!( "✅ Professional markdown report generation" );
println!( "✅ Full PerformanceReport template integration" );
println!( "✅ Real-world use cases and configuration guidance" );
println!( "\n🎯 Ready for production use in performance monitoring workflows!" );
}
#[ cfg( not( feature = "enabled" ) ) ]
fn main()
{
println!( "This example requires the 'enabled' feature." );
println!( "Run with: cargo run --example regression_analysis_comprehensive --features enabled" );
}