#![allow(clippy::expect_used)]
use core::hint::black_box;
use std::path::Path;
use std::sync::Arc;
use criterion::BatchSize;
use criterion::Criterion;
use criterion::criterion_group;
use criterion::criterion_main;
use polyplug::Runtime;
use polyplug_abi::GuestContractHandle;
use polyplug_abi::GuestContractInterface;
use polyplug_abi::runtime::RuntimeConfig;
use polyplug_utils::GuestContractId;
#[path = "../tests/common/mod.rs"]
mod common;
use common::TestNativeLoader;
const TEST_PLUGIN_DIR: &str = env!("TEST_PLUGIN_DIR");
const RELOAD_PLUGIN_V1_DIR: &str = env!("RELOAD_PLUGIN_V1_DIR");
const RELOAD_PLUGIN_V2_DIR: &str = env!("RELOAD_PLUGIN_V2_DIR");
fn fresh_runtime() -> Arc<Runtime> {
Runtime::builder()
.loader(TestNativeLoader::new())
.build()
.expect("runtime build must succeed")
}
fn fresh_hot_reload_runtime() -> Arc<Runtime> {
Runtime::builder()
.config(RuntimeConfig {
hot_reload_enabled: true,
..RuntimeConfig::default()
})
.loader(TestNativeLoader::new())
.build()
.expect("hot-reload runtime build must succeed")
}
fn bench_amortization(c: &mut Criterion) {
let mut group: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> =
c.benchmark_group("amortization");
group.bench_function("load_bundle", |b| {
b.iter_batched(
fresh_runtime,
|runtime: Arc<Runtime>| {
runtime
.load_bundle(black_box(Path::new(TEST_PLUGIN_DIR)))
.expect("load_bundle must succeed");
runtime
},
BatchSize::SmallInput,
);
});
let resolved_runtime: Arc<Runtime> = fresh_runtime();
resolved_runtime
.load_bundle(Path::new(TEST_PLUGIN_DIR))
.expect("preload for resolve bench");
let contract_id: u64 = GuestContractId::new("test.add", 1).id();
group.bench_function("find_and_resolve", |b| {
b.iter(|| {
let handle: GuestContractHandle = resolved_runtime
.find_guest_contract(black_box(contract_id), 0)
.expect("find_guest_contract must succeed");
let interface: *const GuestContractInterface = resolved_runtime
.resolve_guest_contract(handle)
.expect("resolve_guest_contract must succeed");
black_box(interface)
});
});
let reload_runtime: Arc<Runtime> = fresh_hot_reload_runtime();
reload_runtime
.load_bundle(Path::new(RELOAD_PLUGIN_V1_DIR))
.expect("preload v1 for reload bench");
group.bench_function("hot_reload_swap", |b| {
b.iter(|| {
reload_runtime
.reload_bundle(black_box(Path::new(RELOAD_PLUGIN_V2_DIR)))
.expect("reload_bundle must succeed");
});
});
group.finish();
}
criterion_group!(benches, bench_amortization);
criterion_main!(benches);