use std::hint::black_box;
use criterion::{criterion_group, criterion_main, Criterion};
use subetha_cxc::{SharedUniversal, UniversalStrategy as Strategy};
fn tmp_base(name: &str) -> std::path::PathBuf {
let mut p = std::env::temp_dir();
let pid = std::process::id();
p.push(format!("subetha-bench-universal-{name}-{pid}"));
p
}
fn cleanup(base: &std::path::Path) {
let stem = base.file_name().unwrap().to_string_lossy().to_string();
let parent = base.parent().unwrap_or_else(|| std::path::Path::new(""));
if let Ok(entries) = std::fs::read_dir(parent) {
for e in entries.flatten() {
let name = e.file_name().to_string_lossy().to_string();
if name.starts_with(&stem) {
std::fs::remove_file(e.path()).ok();
}
}
}
}
fn contains_vec_vs_map_n1k(c: &mut Criterion) {
const N: u64 = 1024;
let base = tmp_base("contains-n1k");
let u: SharedUniversal<u64> = SharedUniversal::create(&base, N as usize).unwrap();
for k in 0..N { u.insert(k).unwrap(); }
c.bench_function("universal.contains/vec_n1k", |b| {
b.iter(|| black_box(u.contains(black_box(&999u64)).unwrap()));
});
u.migrate_to(Strategy::Map).unwrap();
c.bench_function("universal.contains/map_n1k", |b| {
b.iter(|| black_box(u.contains(black_box(&999u64)).unwrap()));
});
drop(u);
cleanup(&base);
}
fn migration_cost_n1k(c: &mut Criterion) {
const N: u64 = 1024;
let base = tmp_base("migrate-n1k");
let u: SharedUniversal<u64> = SharedUniversal::create(&base, N as usize).unwrap();
for k in 0..N { u.insert(k).unwrap(); }
let mut toggle = false;
c.bench_function("universal.migrate_vec_to_map_n1k", |b| {
b.iter(|| {
let target = if toggle { Strategy::Vec } else { Strategy::Map };
u.migrate_to(target).unwrap();
toggle = !toggle;
});
});
drop(u);
cleanup(&base);
}
fn insert_vec_vs_map_n1k(c: &mut Criterion) {
const N: u64 = 1024;
let base_v = tmp_base("ins-vec");
let base_m = tmp_base("ins-map");
let uv: SharedUniversal<u64> = SharedUniversal::create(&base_v, (N * 2) as usize).unwrap();
let um: SharedUniversal<u64> = SharedUniversal::create(&base_m, (N * 2) as usize).unwrap();
um.migrate_to(Strategy::Map).unwrap();
const PER_ITER: u64 = 256; c.bench_function("universal.insert/vec_n1k", |b| {
b.iter_batched(
|| uv.clear().expect("vec clear"),
|_| for k in 0..PER_ITER {
uv.insert(black_box(k)).expect("vec insert");
},
criterion::BatchSize::PerIteration,
);
});
c.bench_function("universal.insert/map_n1k", |b| {
b.iter_batched(
|| um.clear().expect("map clear"),
|_| for k in 0..PER_ITER {
um.insert(black_box(k)).expect("map insert");
},
criterion::BatchSize::PerIteration,
);
});
drop(uv);
drop(um);
cleanup(&base_v);
cleanup(&base_m);
}
criterion_group!(benches,
contains_vec_vs_map_n1k,
migration_cost_n1k,
insert_vec_vs_map_n1k,
);
criterion_main!(benches);