use std::hint::black_box;
use std::path::{Path, PathBuf};
use std::process::Command;
use audio_plugin_bsd::PluginLoader;
use criterion::{criterion_group, criterion_main, Criterion};
fn ensure_test_plugin_built() -> PathBuf {
let cargo = std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
let status = Command::new(&cargo)
.args(["build", "--example", "test_plugin"])
.status()
.unwrap_or_else(|e| panic!("failed to spawn `{cargo:?} build --example test_plugin`: {e}"));
assert!(
status.success(),
"`cargo build --example test_plugin` failed (exit {:?})",
status.code()
);
let (prefix, suffix) = platform_prefix_suffix();
let file_name = format!("{prefix}test_plugin{suffix}");
let target_dir = std::env::var_os("CARGO_TARGET_DIR")
.map(PathBuf::from)
.or_else(|| {
std::env::var_os("CARGO_MANIFEST_DIR").map(|md| PathBuf::from(md).join("target"))
})
.expect("CARGO_MANIFEST_DIR or CARGO_TARGET_DIR must be set by the bench harness");
let profiles: [&str; 2] = if cfg!(debug_assertions) {
["debug", "release"]
} else {
["release", "debug"]
};
for profile in profiles {
let candidate = target_dir.join(profile).join("examples").join(&file_name);
if candidate.is_file() {
return candidate;
}
}
panic!(
"test_plugin artifact `{file_name}` not found under {target_dir:?} \
(probed profiles: debug, release)"
);
}
fn platform_prefix_suffix() -> (&'static str, &'static str) {
if cfg!(target_os = "windows") {
("", ".dll")
} else if cfg!(target_os = "macos") {
("lib", ".dylib")
} else {
("lib", ".so")
}
}
fn plugin_benches(c: &mut Criterion) {
let so = ensure_test_plugin_built();
let so: &Path = &so;
c.bench_function("plugin_load_full_lifecycle", |b| {
b.iter(|| {
let mut loader = PluginLoader::new();
let id = loader.load(so).expect("plugin load");
let _meta = loader.metadata(id).expect("metadata lookup");
let node = loader.instantiate(id).expect("instantiate");
drop(node);
loader.unload(id).expect("unload");
});
});
c.bench_function("plugin_instantiate_only", |b| {
let mut loader = PluginLoader::new();
let id = loader.load(so).expect("plugin load for instantiate bench");
b.iter(|| {
let node = loader.instantiate(id).expect("instantiate");
black_box(node);
});
loader.unload(id).expect("cleanup unload");
});
}
criterion_group!(benches, plugin_benches);
criterion_main!(benches);