use amberfork_align::{DiffParams, LexicalCost, diff};
use amberfork_model::{Run, SchemaVersion, Step};
use criterion::{BenchmarkId, Criterion, SamplingMode, criterion_group, criterion_main};
use std::path::{Path, PathBuf};
const SIZES: &[usize] = &[125, 250, 500, 1000];
fn fixture_dir() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../bench/fixtures/chimera_noise_seed42_dev")
}
fn side_steps(side: char) -> Vec<Step> {
let dir = fixture_dir();
let mut files: Vec<PathBuf> = std::fs::read_dir(&dir)
.unwrap_or_else(|e| panic!("read {}: {e}", dir.display()))
.filter_map(Result::ok)
.map(|e| e.path())
.filter(|p| {
p.file_name()
.and_then(|n| n.to_str())
.is_some_and(|n| n.starts_with(&format!("{side}_")) && n.ends_with(".json"))
})
.collect();
files.sort();
assert!(
!files.is_empty(),
"no {side}_*.json runs in {}",
dir.display()
);
files
.iter()
.flat_map(|path| {
let text = std::fs::read_to_string(path)
.unwrap_or_else(|e| panic!("read {}: {e}", path.display()));
let run: Run = serde_json::from_str(&text)
.unwrap_or_else(|e| panic!("parse {}: {e}", path.display()));
run.steps
})
.collect()
}
fn stitched_run(id: &str, source: &[Step], n: usize) -> Run {
let steps = source
.iter()
.cycle()
.take(n)
.cloned()
.enumerate()
.map(|(idx, mut step)| {
step.idx = idx;
step.parent_idx = None;
step
})
.collect();
Run {
schema_version: SchemaVersion::current(),
id: id.to_string(),
task: Some("scale probe (issue #16)".to_string()),
outcome: None,
steps,
edges: None,
}
}
fn bench_diff_scale(c: &mut Criterion) {
let a_source = side_steps('a');
let b_source = side_steps('b');
let mut group = c.benchmark_group("diff_scale");
group.sampling_mode(SamplingMode::Flat);
group.sample_size(10);
for &n in SIZES {
let reference = stitched_run("stitched-a", &a_source, n);
let observed = stitched_run("stitched-b", &b_source, n);
group.bench_with_input(BenchmarkId::from_parameter(n), &n, |bencher, _| {
bencher.iter(|| {
diff(&reference, &observed, &LexicalCost, &DiffParams::default())
.expect("under the size guard")
});
});
}
group.finish();
}
criterion_group!(benches, bench_diff_scale);
criterion_main!(benches);