use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use std::path::Path;
use std::time::Duration;
use wasm4pm::discovery::discover_dfg;
use wasm4pm::simd_streaming_dfg::discover_dfg_simd_handle;
use wasm4pm::xes_format::validate_and_parse_xes;
#[path = "helpers.rs"]
mod helpers;
use helpers::{is_fast_mode, store_log, ACTIVITY_KEY};
struct Dataset {
label: &'static str,
handle: String,
events: u64,
}
fn load_datasets() -> Vec<Dataset> {
let mut specs: Vec<(&str, &str)> = vec![
("sepsis", "bench_data/sepsis.xes"),
("roadtraffic", "bench_data/roadtraffic100traces.xes"),
];
if !is_fast_mode() {
specs.push(("bpi2020_travel", "bench_data/bpi2020_travel.xes"));
}
let mut out = Vec::new();
for (label, rel) in specs {
let path = Path::new(rel);
if !path.exists() {
eprintln!(
"streaming bench: dataset '{}' missing at {}, skipping",
label, rel
);
continue;
}
let content = std::fs::read_to_string(path)
.unwrap_or_else(|e| panic!("bench: failed to read {}: {}", rel, e));
let log = validate_and_parse_xes(&content)
.unwrap_or_else(|e| panic!("bench: failed to parse {}: {}", rel, e));
let events = log.event_count() as u64;
assert!(
events > 0,
"bench: real dataset '{}' parsed to 0 events",
label
);
let handle = store_log(log);
out.push(Dataset {
label,
handle,
events,
});
}
assert!(
!out.is_empty(),
"bench: no real datasets available under bench_data/ — cannot benchmark streaming DFG"
);
out
}
fn bench_dfg_scalar(c: &mut Criterion) {
let datasets = load_datasets();
let mut group = c.benchmark_group("streaming/dfg_scalar");
group.measurement_time(Duration::from_secs(8));
group.warm_up_time(Duration::from_secs(2));
group.sample_size(30);
if is_fast_mode() {
helpers::fast_group(&mut group);
} else {
helpers::full_group(&mut group);
}
for ds in &datasets {
group.throughput(Throughput::Elements(ds.events));
group.bench_with_input(BenchmarkId::new("dataset", ds.label), &ds.handle, |b, h| {
b.iter(|| {
black_box(discover_dfg(black_box(h.as_str()), black_box(ACTIVITY_KEY)).unwrap())
})
});
}
group.finish();
}
fn bench_dfg_simd_handle(c: &mut Criterion) {
let datasets = load_datasets();
let mut group = c.benchmark_group("streaming/dfg_simd_handle");
group.measurement_time(Duration::from_secs(8));
group.warm_up_time(Duration::from_secs(2));
group.sample_size(30);
if is_fast_mode() {
helpers::fast_group(&mut group);
} else {
helpers::full_group(&mut group);
}
for ds in &datasets {
group.throughput(Throughput::Elements(ds.events));
group.bench_with_input(BenchmarkId::new("dataset", ds.label), &ds.handle, |b, h| {
b.iter(|| {
black_box(
discover_dfg_simd_handle(black_box(h.as_str()), black_box(ACTIVITY_KEY))
.unwrap(),
)
})
});
}
group.finish();
}
criterion_group!(streaming_benches, bench_dfg_scalar, bench_dfg_simd_handle);
criterion_main!(streaming_benches);