use arcweight::algorithms::difference;
use arcweight::prelude::*;
use criterion::{criterion_group, criterion_main, Criterion};
use std::hint::black_box;
fn create_linear_fst(size: usize, symbol_offset: u32) -> VectorFst<TropicalWeight> {
let mut fst = VectorFst::new();
if size == 0 {
return fst;
}
let states: Vec<_> = (0..size).map(|_| fst.add_state()).collect();
fst.set_start(states[0]);
fst.set_final(states[size - 1], TropicalWeight::one());
for i in 0..size - 1 {
fst.add_arc(
states[i],
Arc::new(
(i % 26 + 97 + symbol_offset as usize) as u32,
(i % 26 + 97 + symbol_offset as usize) as u32,
TropicalWeight::new(1.0),
states[i + 1],
),
);
}
fst
}
fn bench_difference_linear(c: &mut Criterion) {
let mut group = c.benchmark_group("difference_linear");
for size in [10, 100, 500].iter() {
let fst1 = create_linear_fst(*size, 0);
let fst2 = create_linear_fst(*size, 0);
group.bench_function(format!("identical_linear_{size}"), |b| {
b.iter(|| {
let result: VectorFst<TropicalWeight> =
difference(black_box(&fst1), black_box(&fst2)).unwrap();
black_box(result)
})
});
let fst3 = create_linear_fst(*size, 5);
group.bench_function(format!("partial_overlap_linear_{size}"), |b| {
b.iter(|| {
let result: VectorFst<TropicalWeight> =
difference(black_box(&fst1), black_box(&fst3)).unwrap();
black_box(result)
})
});
}
group.finish();
}
fn bench_difference_disjoint(c: &mut Criterion) {
let mut group = c.benchmark_group("difference_disjoint");
for size in [50, 200, 500].iter() {
let fst1 = create_linear_fst(*size, 0); let fst2 = create_linear_fst(*size, 26);
group.bench_function(format!("disjoint_{size}"), |b| {
b.iter(|| {
let result: VectorFst<TropicalWeight> =
difference(black_box(&fst1), black_box(&fst2)).unwrap();
black_box(result)
})
});
}
group.finish();
}
fn bench_difference_empty(c: &mut Criterion) {
let mut group = c.benchmark_group("difference_empty");
let empty_fst = VectorFst::<TropicalWeight>::new();
let linear_fst = create_linear_fst(100, 0);
group.bench_function("empty_x_linear", |b| {
b.iter(|| {
match difference::<TropicalWeight, _, _, VectorFst<TropicalWeight>>(
black_box(&empty_fst),
black_box(&linear_fst),
) {
Ok(result) => black_box(result),
Err(_) => black_box(VectorFst::<TropicalWeight>::new()),
}
})
});
group.bench_function("linear_x_empty", |b| {
b.iter(|| {
match difference::<TropicalWeight, _, _, VectorFst<TropicalWeight>>(
black_box(&linear_fst),
black_box(&empty_fst),
) {
Ok(result) => black_box(result),
Err(_) => black_box(VectorFst::<TropicalWeight>::new()),
}
})
});
group.finish();
}
criterion_group!(
benches,
bench_difference_linear,
bench_difference_disjoint,
bench_difference_empty
);
criterion_main!(benches);