use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use simu::SimEnv;
use simu::{Container, PreemptiveResource, PriorityResource, Resource};
fn timeout_throughput(c: &mut Criterion) {
let mut group = c.benchmark_group("timeout_throughput");
for n in [1_000_u64, 10_000, 100_000] {
group.bench_with_input(BenchmarkId::from_parameter(n), &n, |b, &n| {
b.iter(|| {
let mut env = SimEnv::with_seed(0);
for i in 0..n {
let h = env.handle();
env.spawn(async move {
h.timeout(i as f64).await;
});
}
env.run();
});
});
}
group.finish();
}
fn resource_contention(c: &mut Criterion) {
let mut group = c.benchmark_group("resource_contention");
for n in [100_u32, 1_000, 10_000] {
group.bench_with_input(BenchmarkId::from_parameter(n), &n, |b, &n| {
b.iter(|| {
let mut env = SimEnv::with_seed(0);
let resource = Resource::new(1);
for _ in 0..n {
let h = env.handle();
let r = resource.clone();
env.spawn(async move {
let _guard = r.request().await;
h.timeout(1.0).await;
});
}
env.run();
});
});
}
group.finish();
}
fn event_broadcast(c: &mut Criterion) {
let mut group = c.benchmark_group("event_broadcast");
for n in [100_u32, 1_000, 10_000] {
group.bench_with_input(BenchmarkId::from_parameter(n), &n, |b, &n| {
b.iter(|| {
let mut env = SimEnv::with_seed(0);
let (trigger, awaitable) = env.event();
for _ in 0..n {
let h = env.handle();
let aw = awaitable.clone();
env.spawn(async move {
aw.await;
let _ = h.now();
});
}
{
let h = env.handle();
env.spawn(async move {
h.timeout(1.0).await;
trigger.fire();
});
}
env.run();
});
});
}
group.finish();
}
fn run_mixed(n: u32) {
let mut env = SimEnv::with_seed(0);
let nurse = Resource::new(1);
let beds = Resource::new(3);
{
let nurse = nurse.clone();
let beds = beds.clone();
let h = env.handle();
for i in 0..n {
let h = h.clone();
let nurse = nurse.clone();
let beds = beds.clone();
env.spawn(async move {
h.timeout(i as f64).await; let _nurse_guard = nurse.request().await;
h.timeout(5.0).await;
drop(_nurse_guard);
let _bed_guard = beds.request().await;
h.timeout(20.0).await;
});
}
}
env.run();
}
fn mixed_workload(c: &mut Criterion) {
let mut group = c.benchmark_group("mixed_workload");
for n in [100_u32, 1_000, 10_000] {
group.bench_with_input(BenchmarkId::from_parameter(n), &n, |b, &n| {
b.iter(|| run_mixed(n));
});
}
group.finish();
}
fn monte_carlo_scaling(c: &mut Criterion) {
let mut group = c.benchmark_group("monte_carlo_scaling");
for k in [1_u64, 2, 4, 8] {
group.bench_with_input(BenchmarkId::from_parameter(k), &k, |b, &k| {
b.iter(|| {
simu::monte_carlo::run(0..k, |_seed| run_mixed(100));
});
});
}
group.finish();
}
fn priority_contention(c: &mut Criterion) {
let mut group = c.benchmark_group("priority_contention");
for n in [100_u32, 1_000, 10_000] {
group.bench_with_input(BenchmarkId::from_parameter(n), &n, |b, &n| {
b.iter(|| {
let mut env = SimEnv::with_seed(0);
let resource = PriorityResource::new(1);
for i in 0..n {
let h = env.handle();
let r = resource.clone();
let prio = i % 4; env.spawn(async move {
let _guard = r.request(prio).await;
h.timeout(1.0).await;
});
}
env.run();
});
});
}
group.finish();
}
fn preemptive_contention(c: &mut Criterion) {
let mut group = c.benchmark_group("preemptive_contention");
for n in [100_u32, 1_000, 10_000] {
group.bench_with_input(BenchmarkId::from_parameter(n), &n, |b, &n| {
b.iter(|| {
let mut env = SimEnv::with_seed(0);
let resource = PreemptiveResource::new(2);
for i in 0..n {
let h = env.handle();
let r = resource.clone();
let prio = i % 2; env.spawn(async move {
let guard = r.request(prio).await;
simu::any_of![h.timeout(1.0), guard.preempted()].await;
});
}
env.run();
});
});
}
group.finish();
}
fn container_throughput(c: &mut Criterion) {
let mut group = c.benchmark_group("container_throughput");
for n in [100_u32, 1_000, 10_000] {
group.bench_with_input(BenchmarkId::from_parameter(n), &n, |b, &n| {
b.iter(|| {
let mut env = SimEnv::with_seed(0);
let tank = Container::new(f64::from(n) + 1.0, 0.0);
for _ in 0..n {
let c = tank.clone();
env.spawn(async move {
c.get(1.0).await;
});
}
for _ in 0..n {
let h = env.handle();
let c = tank.clone();
env.spawn(async move {
h.timeout(1.0).await;
c.put(1.0).await;
});
}
env.run();
});
});
}
group.finish();
}
criterion_group!(
benches,
timeout_throughput,
resource_contention,
event_broadcast,
mixed_workload,
monte_carlo_scaling,
priority_contention,
preemptive_contention,
container_throughput,
);
criterion_main!(benches);