//! Performance benchmarks for event handling //! //! Measures event handling latency to ensure TUI remains responsive: //! - Target: <1ms for keyboard event handling //! - Target: <2ms for screen navigation //! //! Run with: `cargo bench -p syntaxis-tui --bench event_handling` use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use std::hint::black_box; fn keyboard_event_parsing_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("keyboard_events"); // Target sub-millisecond event parsing group.significance_level(0.1); group.sample_size(10000); // Simulate keyboard event handling group.bench_function("key_event_creation", |b| { b.iter(|| { let _key = black_box(65u8); // 'A' key let _modifiers = black_box(0u8); // No modifiers }) }); // Simulate event dispatch group.bench_function("event_dispatch_routing", |b| { b.iter(|| { let key_code = black_box(65u8); let _screen = if key_code > 90 { "detail" } else { "list" }; }) }); group.finish(); } fn navigation_performance_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("navigation"); group.significance_level(0.1); group.sample_size(1000); // Benchmark list navigation for list_size in [10, 100, 1000].iter() { group.bench_with_input( BenchmarkId::from_parameter(format!("navigate_{}_items", list_size)), list_size, |b, &list_size| { b.iter(|| { let current_index = black_box(5); let next_index = (current_index + 1) % list_size; let _ = black_box(next_index); }) }, ); } // Benchmark wrapping navigation group.bench_function("navigate_with_wrapping", |b| { b.iter(|| { let list_size = black_box(20); let current_index = black_box(19); let next = (current_index + 1) % list_size; let _ = black_box(next); }) }); group.finish(); } fn screen_transition_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("screen_transitions"); group.significance_level(0.1); group.sample_size(1000); // Simulate screen transition overhead group.bench_function("transition_projects_to_detail", |b| { b.iter(|| { let _from_screen = black_box("ProjectsList"); let _to_screen = black_box("ProjectDetail"); let _ = black_box(true); // dirty flag set }) }); group.bench_function("transition_detail_to_security", |b| { b.iter(|| { let _from_screen = black_box("ProjectDetail"); let _to_screen = black_box("Security"); let _ = black_box(true); }) }); // Benchmark all possible transitions for transition in [ "projects_to_detail", "projects_to_security", "detail_to_projects", "security_to_projects", ] .iter() { group.bench_function(BenchmarkId::from_parameter(*transition), |b| { b.iter(|| { let _ = black_box(true); // dirty flag }) }); } group.finish(); } fn dirty_flag_overhead_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("dirty_flag"); group.significance_level(0.1); group.sample_size(10000); // Benchmark dirty flag operations group.bench_function("set_dirty", |b| { b.iter(|| { let mut dirty = black_box(false); let _ = black_box(dirty); dirty = true; let _ = black_box(dirty); }) }); group.bench_function("clear_dirty", |b| { b.iter(|| { let mut dirty = black_box(true); let _ = black_box(dirty); dirty = false; let _ = black_box(dirty); }) }); // Benchmark conditional rendering based on dirty flag group.bench_function("conditional_render_check", |b| { b.iter(|| { let dirty = black_box(true); if dirty { let _ = black_box("render"); } else { let _ = black_box("skip"); } }) }); group.finish(); } criterion_group!( benches, keyboard_event_parsing_benchmark, navigation_performance_benchmark, screen_transition_benchmark, dirty_flag_overhead_benchmark ); criterion_main!(benches);