// Comprehensive latency benchmarks for RuVector Nervous System components // Measures P50, P99, P99.9 percentiles for all critical operations use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use std::time::Duration; // Note: Import actual types when implemented // use ruvector_nervous_system::*; // ============================================================================ // Event Bus Benchmarks // ============================================================================ fn benchmark_event_bus(c: &mut Criterion) { let mut group = c.benchmark_group("event_bus"); group.warm_up_time(Duration::from_secs(1)); group.measurement_time(Duration::from_secs(5)); // Event publish latency (target: <10μs) group.bench_function("event_publish", |b| { // let bus = EventBus::new(1000); // let event = Event::new("test", vec![0.0; 128]); b.iter(|| { // bus.publish(black_box(event.clone())) // Placeholder until EventBus is implemented black_box(42); }); }); // Event delivery from bounded queue (target: <5μs) group.bench_function("bounded_queue_delivery", |b| { // let queue = BoundedQueue::new(1000); b.iter(|| { // queue.pop() black_box(42); }); }); // Priority routing (target: <20μs) group.bench_function("priority_routing", |b| { // let router = PriorityRouter::new(); // let event = Event::with_priority("test", vec![0.0; 128], Priority::High); b.iter(|| { // router.route(black_box(&event)) black_box(42); }); }); group.finish(); } // ============================================================================ // HDC (Hyperdimensional Computing) Benchmarks // ============================================================================ fn benchmark_hdc(c: &mut Criterion) { let mut group = c.benchmark_group("hdc"); group.warm_up_time(Duration::from_millis(500)); let mut rng = StdRng::seed_from_u64(42); // Vector binding (target: <100ns) let vec_a = generate_bitvector(&mut rng, 10000); let vec_b = generate_bitvector(&mut rng, 10000); group.bench_function("vector_binding", |bencher| { bencher.iter(|| xor_bitvectors(black_box(&vec_a), black_box(&vec_b))); }); // Vector bundling (target: <500ns) let bundle_vectors: Vec<_> = (0..10) .map(|_| generate_bitvector(&mut rng, 10000)) .collect(); group.bench_function("vector_bundling", |bencher| { bencher.iter(|| majority_bitvectors(black_box(&bundle_vectors))); }); // Hamming distance (target: <100ns) let ham_a = generate_bitvector(&mut rng, 10000); let ham_b = generate_bitvector(&mut rng, 10000); group.bench_function("hamming_distance", |bencher| { bencher.iter(|| hamming_distance(black_box(&ham_a), black_box(&ham_b))); }); // Similarity check (target: <200ns) let sim_a = generate_bitvector(&mut rng, 10000); let sim_b = generate_bitvector(&mut rng, 10000); group.bench_function("similarity_check", |bencher| { bencher.iter(|| hdc_similarity(black_box(&sim_a), black_box(&sim_b))); }); group.finish(); } // ============================================================================ // WTA (Winner-Take-All) Benchmarks // ============================================================================ fn benchmark_wta(c: &mut Criterion) { let mut group = c.benchmark_group("wta"); let mut rng = StdRng::seed_from_u64(42); // Single winner selection (target: <1μs) group.bench_function("single_winner", |b| { let inputs: Vec = (0..1000).map(|_| rng.gen()).collect(); b.iter(|| { // wta.select_winner(black_box(&inputs)) argmax(black_box(&inputs)) }); }); // k-WTA with k=5 (target: <5μs) group.bench_function("k_wta_5", |b| { let inputs: Vec = (0..1000).map(|_| rng.gen()).collect(); b.iter(|| { // wta.select_k_winners(black_box(&inputs), 5) argmax_k(black_box(&inputs), 5) }); }); // Lateral inhibition update (target: <10μs) group.bench_function("lateral_inhibition", |b| { let inputs: Vec = (0..1000).map(|_| rng.gen()).collect(); b.iter(|| { // lateral_inhibition.update(black_box(&inputs)) apply_inhibition(black_box(&inputs), 0.5) }); }); group.finish(); } // ============================================================================ // Hopfield Network Benchmarks // ============================================================================ fn benchmark_hopfield(c: &mut Criterion) { let mut group = c.benchmark_group("hopfield"); group.warm_up_time(Duration::from_secs(1)); group.measurement_time(Duration::from_secs(5)); let mut rng = StdRng::seed_from_u64(42); // Pattern retrieval with varying pattern counts for num_patterns in [10, 100, 1000].iter() { group.bench_with_input( BenchmarkId::new("pattern_retrieval", num_patterns), num_patterns, |b, &num_patterns| { // let hopfield = ModernHopfield::new(512, 100.0); // for _ in 0..num_patterns { // hopfield.store(generate_random_vector(&mut rng, 512)); // } let query = generate_random_vector(&mut rng, 512); b.iter(|| { // hopfield.retrieve(black_box(&query)) // Placeholder black_box(query.clone()) }); }, ); } // Pattern storage (target: <100μs) group.bench_function("pattern_storage", |b| { // let hopfield = ModernHopfield::new(512, 100.0); let pattern = generate_random_vector(&mut rng, 512); b.iter(|| { // hopfield.store(black_box(pattern.clone())) black_box(42); }); }); // Energy computation (target: <50μs) group.bench_function("energy_computation", |b| { // let hopfield = ModernHopfield::new(512, 100.0); let state = generate_random_vector(&mut rng, 512); b.iter(|| { // hopfield.energy(black_box(&state)) compute_energy_placeholder(black_box(&state)) }); }); group.finish(); } // ============================================================================ // Pattern Separation Benchmarks // ============================================================================ fn benchmark_pattern_separation(c: &mut Criterion) { let mut group = c.benchmark_group("pattern_separation"); let mut rng = StdRng::seed_from_u64(42); // Encoding with orthogonalization (target: <500μs) group.bench_function("orthogonal_encoding", |b| { // let encoder = PatternSeparator::new(512); let input = generate_random_vector(&mut rng, 512); b.iter(|| { // encoder.encode(black_box(&input)) orthogonalize_placeholder(black_box(&input)) }); }); // Collision detection (target: <100μs) group.bench_function("collision_detection", |b| { let encoded = generate_random_vector(&mut rng, 512); b.iter(|| { // detector.check_collision(black_box(&encoded)) black_box(false) }); }); // Decorrelation (target: <200μs) group.bench_function("decorrelation", |b| { let input = generate_random_vector(&mut rng, 512); b.iter(|| { // decorrelator.decorrelate(black_box(&input)) decorrelate_placeholder(black_box(&input)) }); }); group.finish(); } // ============================================================================ // Plasticity Benchmarks // ============================================================================ fn benchmark_plasticity(c: &mut Criterion) { let mut group = c.benchmark_group("plasticity"); let mut rng = StdRng::seed_from_u64(42); // E-prop gradient update (target: <100μs) group.bench_function("eprop_gradient_update", |b| { // let eprop = EPropLearner::new(100, 0.01); let gradient = generate_random_vector(&mut rng, 100); b.iter(|| { // eprop.update_gradients(black_box(&gradient)) black_box(42); }); }); // BTSP eligibility trace (target: <50μs) group.bench_function("btsp_eligibility_trace", |b| { // let btsp = BTSPLearner::new(100, 0.01, 1000); b.iter(|| { // btsp.update_eligibility(black_box(0.5)) black_box(42); }); }); // EWC Fisher matrix update (target: <1ms) group.bench_function("ewc_fisher_update", |b| { // let ewc = EWCLearner::new(1000); let gradient = generate_random_vector(&mut rng, 1000); b.iter(|| { // ewc.update_fisher(black_box(&gradient)) black_box(42); }); }); group.finish(); } // ============================================================================ // Cognitum Integration Benchmarks // ============================================================================ fn benchmark_cognitum(c: &mut Criterion) { let mut group = c.benchmark_group("cognitum"); // Reflex event→action (target: <100μs) group.bench_function("reflex_latency", |b| { // let reflex = ReflexArc::new(); // let event = Event::new("sensor", vec![0.5; 128]); b.iter(|| { // reflex.process(black_box(&event)) black_box(42); }); }); // v0 adapter dispatch (target: <50μs) group.bench_function("v0_adapter_dispatch", |b| { // let adapter = V0Adapter::new(); b.iter(|| { // adapter.dispatch(black_box(&event)) black_box(42); }); }); group.finish(); } // ============================================================================ // Helper Functions (Placeholders) // ============================================================================ fn generate_bitvector(rng: &mut StdRng, size: usize) -> Vec { (0..(size + 63) / 64).map(|_| rng.gen()).collect() } fn generate_random_vector(rng: &mut StdRng, size: usize) -> Vec { (0..size).map(|_| rng.gen()).collect() } fn xor_bitvectors(a: &[u64], b: &[u64]) -> Vec { a.iter().zip(b.iter()).map(|(x, y)| x ^ y).collect() } fn majority_bitvectors(vectors: &[Vec]) -> Vec { let len = vectors[0].len(); (0..len) .map(|i| vectors.iter().map(|v| v[i]).fold(0u64, |acc, x| acc ^ x)) .collect() } fn hamming_distance(a: &[u64], b: &[u64]) -> u32 { a.iter() .zip(b.iter()) .map(|(x, y)| (x ^ y).count_ones()) .sum() } fn hdc_similarity(a: &[u64], b: &[u64]) -> f32 { let total_bits = a.len() * 64; let hamming = hamming_distance(a, b) as f32; 1.0 - (hamming / total_bits as f32) } fn argmax(inputs: &[f32]) -> usize { inputs .iter() .enumerate() .max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap()) .unwrap() .0 } fn argmax_k(inputs: &[f32], k: usize) -> Vec { let mut indexed: Vec<_> = inputs.iter().enumerate().collect(); indexed.sort_by(|(_, a), (_, b)| b.partial_cmp(a).unwrap()); indexed.iter().take(k).map(|(i, _)| *i).collect() } fn apply_inhibition(inputs: &[f32], strength: f32) -> Vec { let max_val = inputs.iter().cloned().fold(f32::NEG_INFINITY, f32::max); inputs .iter() .map(|&x| (x - strength * max_val).max(0.0)) .collect() } fn compute_energy_placeholder(state: &[f32]) -> f32 { -state.iter().map(|x| x * x).sum::() } fn orthogonalize_placeholder(input: &[f32]) -> Vec { let norm: f32 = input.iter().map(|x| x * x).sum::().sqrt(); input.iter().map(|x| x / norm).collect() } fn decorrelate_placeholder(input: &[f32]) -> Vec { let mean: f32 = input.iter().sum::() / input.len() as f32; input.iter().map(|x| x - mean).collect() } // ============================================================================ // Criterion Configuration // ============================================================================ criterion_group!( benches, benchmark_event_bus, benchmark_hdc, benchmark_wta, benchmark_hopfield, benchmark_pattern_separation, benchmark_plasticity, benchmark_cognitum, ); criterion_main!(benches);