/* Generic tree structures for storage of spatial data.
Copyright (C) 2023 Alexander Pyattaev
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use freelist as libfreelist;
use rand::rngs::SmallRng;
use rand::{Rng, SeedableRng};
use std::ops::Index;
use slab::Slab;
trait FlHarness {
fn new() -> Self;
fn add(&mut self, d: u32) -> usize;
fn erase(&mut self, idx: usize);
fn get_value(&self, index: usize) -> &u32;
}
impl FlHarness for Slab {
fn new() -> Self {
Slab::with_capacity(4)
}
fn add(&mut self, d: u32) -> usize {
self.insert(d)
}
fn erase(&mut self, idx: usize) {
self.remove(idx);
}
fn get_value(&self, index: usize) -> &u32 {
&self[index]
}
}
impl FlHarness for libfreelist::FreeList {
fn new() -> Self {
libfreelist::FreeList::new()
}
fn add(&mut self, d: u32) -> usize {
self.add(d).get()
}
fn erase(&mut self, idx: usize) {
self.remove(libfreelist::Idx::new(idx).unwrap())
}
fn get_value(&self, index: usize) -> &u32 {
self.index(libfreelist::Idx::new(index).unwrap())
}
}
fn fill_freelist(n: usize, rng: &mut SmallRng) -> FL {
let mut lst = FL::new();
for _ in 0..n {
let v: u32 = rng.gen_range(0..1024);
lst.add(v);
}
lst
}
fn freelist_eval(c: &mut Criterion, title: &str)
where
FL: FlHarness,
{
let mut group = c.benchmark_group(title);
let mut rng = SmallRng::seed_from_u64(42);
let samples_num = 10;
for depth in [25, 50].iter() {
group.significance_level(0.1).sample_size(samples_num);
group.bench_with_input(BenchmarkId::from_parameter(depth), depth, |b, &depth| {
b.iter(|| {
let mut lst: FL = fill_freelist(depth, &mut rng);
let mut x: u32 = 0;
for n in 1..depth {
x += lst.get_value(n);
lst.erase(n);
}
for n in 0..depth {
lst.add(n as u32);
}
for n in 1..depth {
x += lst.get_value(n);
lst.erase(n);
}
for n in 0..depth {
lst.add(n as u32);
}
black_box(lst);
});
});
}
group.finish();
}
pub fn freelist(c: &mut Criterion) {
freelist_eval::>(c, "freelist library");
freelist_eval::>(c, "freelist slab");
}
criterion_group!(benches, freelist);
criterion_main!(benches);