use std::time::Instant;
use caps_sa::{ExtMemOpts, build_ext_mem, build_ext_mem_for_positions};
fn pathology_text(chr_len: usize, padded_chr_len: usize) -> Vec<u8> {
assert!(padded_chr_len > chr_len, "pad_len must be positive");
let pad_len = padded_chr_len - chr_len;
let mut t = Vec::with_capacity(2 * padded_chr_len + 1);
for i in 0..chr_len {
t.push((i % 4) as u8);
}
t.resize(t.len() + pad_len, 5);
for i in 0..chr_len {
t.push(((i + 1) % 4) as u8);
}
t.resize(t.len() + pad_len, 6);
t.push(7);
t
}
fn run_one(chr_len: usize, padded_chr_len: usize) {
let text = pathology_text(chr_len, padded_chr_len);
let n = text.len();
let positions: Vec<u64> = (0..n as u64).filter(|&p| text[p as usize] < 4).collect();
let n_kept = positions.len();
let n_skipped = n - n_kept;
println!(
"fixture: chr={chr_len} padded_chr={padded_chr_len} t_prime={n} \
ACGT_kept={n_kept} ({:.1}%) spacer/sentinel_skipped={n_skipped} ({:.1}%)",
100.0 * n_kept as f64 / n as f64,
100.0 * n_skipped as f64 / n as f64,
);
let opts = ExtMemOpts {
work_dir: std::env::temp_dir(),
..Default::default()
};
let mut count_old = 0usize;
let t = Instant::now();
build_ext_mem(&text, &opts, |_| {
count_old += 1;
Ok(())
})
.unwrap();
let dt_old = t.elapsed();
assert_eq!(count_old, n);
let mut count_new = 0usize;
let t = Instant::now();
build_ext_mem_for_positions(&text, positions, &opts, |_| {
count_new += 1;
Ok(())
})
.unwrap();
let dt_new = t.elapsed();
assert_eq!(count_new, n_kept);
let speedup = dt_old.as_secs_f64() / dt_new.as_secs_f64();
println!(
" OLD build_ext_mem : {:>10.3} ms ({} positions)",
dt_old.as_secs_f64() * 1e3,
count_old
);
println!(
" NEW build_ext_mem_for_positions : {:>10.3} ms ({} positions)",
dt_new.as_secs_f64() * 1e3,
count_new
);
println!(" speedup : {:>10.1}×", speedup);
println!();
}
fn main() {
println!("== Synthetic spacer-padding pathology bench ==\n");
run_one(20_000, 256 * 1024); run_one(1_000, 256 * 1024);
run_one(10_000, 1024 * 1024);
}