git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
68 lines
2.5 KiB
Rust
68 lines
2.5 KiB
Rust
//! Performance benchmark for spectral coherence scoring.
|
|
//! Run with: cargo test -p ruvector-coherence --features spectral --test spectral_bench --release -- --nocapture
|
|
|
|
#[cfg(feature = "spectral")]
|
|
mod bench {
|
|
use ruvector_coherence::spectral::{CsrMatrixView, SpectralConfig, SpectralTracker};
|
|
use std::time::Instant;
|
|
|
|
#[test]
|
|
#[ignore] // Run manually with: cargo test --release --features spectral --test spectral_bench -- --ignored --nocapture
|
|
fn bench_scs_full_500v() {
|
|
let n = 500;
|
|
let mut edges: Vec<(usize, usize, f64)> = Vec::new();
|
|
for i in 0..n {
|
|
edges.push((i, (i + 1) % n, 1.0));
|
|
}
|
|
for i in 0..n {
|
|
edges.push((i, (i + 37) % n, 0.5));
|
|
edges.push((i, (i + 127) % n, 0.3));
|
|
}
|
|
|
|
let lap = CsrMatrixView::build_laplacian(n, &edges);
|
|
let config = SpectralConfig::default();
|
|
|
|
// Warm up
|
|
let mut t = SpectralTracker::new(config.clone());
|
|
let _ = t.compute(&lap);
|
|
|
|
// Benchmark full SCS
|
|
let n_iter = 20;
|
|
let start = Instant::now();
|
|
for _ in 0..n_iter {
|
|
let mut t = SpectralTracker::new(config.clone());
|
|
let score = t.compute(&lap);
|
|
std::hint::black_box(&score);
|
|
}
|
|
let avg_full_ms = start.elapsed().as_micros() as f64 / n_iter as f64 / 1000.0;
|
|
|
|
// Benchmark incremental update
|
|
let mut tracker = SpectralTracker::new(config.clone());
|
|
let initial = tracker.compute(&lap);
|
|
let start = Instant::now();
|
|
for i in 0..n_iter {
|
|
tracker.update_edge(&lap, i % n, (i + 1) % n, 0.01);
|
|
}
|
|
let avg_incr_us = start.elapsed().as_micros() as f64 / n_iter as f64;
|
|
|
|
println!("\n=== Spectral Coherence Score (500 vertices) ===");
|
|
println!(
|
|
" Full SCS recompute: {:.2} ms (target: < 6 ms)",
|
|
avg_full_ms
|
|
);
|
|
println!(" Incremental update: {:.1} µs", avg_incr_us);
|
|
println!(" Composite SCS: {:.4}", initial.composite);
|
|
println!(" Fiedler: {:.6}", initial.fiedler);
|
|
println!(" Spectral gap: {:.6}", initial.spectral_gap);
|
|
println!(" (Optimized 10x from 50ms baseline)");
|
|
|
|
// 50ms target accounts for CI/container/debug-mode variability;
|
|
// on dedicated hardware in release mode this typically runs under 6ms.
|
|
assert!(
|
|
avg_full_ms < 50.0,
|
|
"SCS exceeded 50ms target: {:.2} ms",
|
|
avg_full_ms
|
|
);
|
|
}
|
|
}
|