#![cfg(feature = "alloc")]
#![allow(
clippy::cast_possible_truncation,
clippy::needless_pass_by_value,
clippy::semicolon_if_nothing_returned
)]
use std::alloc::{GlobalAlloc, Layout, System};
use std::hint::black_box;
use std::time::Duration;
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use sefer_alloc::Heap;
const SIZES: &[usize] = &[16, 64, 256, 1024];
const OPS: usize = 1024;
fn bench_heap_vs_mimalloc_vs_system(c: &mut Criterion) {
let mut group = c.benchmark_group("heap_alloc");
group.sample_size(10);
group.warm_up_time(Duration::from_millis(150));
group.measurement_time(Duration::from_millis(600));
for &size in SIZES {
let layout = Layout::from_size_align(size, 8).unwrap();
group.bench_function(format!("Heap/{size}B"), |b| {
b.iter_batched(
|| {
let mut heap = Heap::new().unwrap();
let mut warm: Vec<*mut u8> = Vec::with_capacity(OPS);
for _ in 0..OPS {
warm.push(heap.alloc(layout));
}
for &p in &warm {
heap.dealloc(p, layout);
}
heap
},
|mut heap| {
let mut ptrs = Vec::with_capacity(OPS);
for _ in 0..OPS {
ptrs.push(heap.alloc(layout));
}
black_box(&ptrs);
for &ptr in &ptrs {
heap.dealloc(ptr, layout);
}
black_box(&heap);
},
BatchSize::SmallInput,
)
});
group.bench_function(format!("mimalloc/{size}B"), |b| {
let mi = mimalloc::MiMalloc;
b.iter(|| {
let mut ptrs = Vec::with_capacity(OPS);
for _ in 0..OPS {
let ptr = unsafe { mi.alloc(layout) };
ptrs.push(ptr);
}
black_box(&ptrs);
for &ptr in &ptrs {
unsafe { mi.dealloc(ptr, layout) };
}
})
});
group.bench_function(format!("System/{size}B"), |b| {
b.iter(|| {
let mut ptrs = Vec::with_capacity(OPS);
for _ in 0..OPS {
let ptr = unsafe { System.alloc(layout) };
ptrs.push(ptr);
}
black_box(&ptrs);
for &ptr in &ptrs {
unsafe { System.dealloc(ptr, layout) };
}
})
});
}
group.finish();
}
criterion_group!(benches, bench_heap_vs_mimalloc_vs_system);
criterion_main!(benches);