use cgmath::Vector3;
use criterion::{criterion_group, criterion_main, Criterion};
use rand::rngs::SmallRng;
use rand::{Rng, SeedableRng};
use spatial_hash_3d::*;
use std::hint::black_box;
#[derive(Debug)]
pub struct Data {
some_data: u32,
}
impl Default for Data {
fn default() -> Self {
Data { some_data: 0 }
}
}
fn create_and_fill(x: u32, y: u32, z: u32) -> SpatialHashGrid<Data> {
let mut sh: SpatialHashGrid<Data> =
SpatialHashGrid::new(x as usize, y as usize, z as usize, Data::default);
let mut count = 0;
for (i, j, k) in itertools::iproduct!(0..x, 0..y, 0..z) {
let pos = Vector3::new(i, j, k);
sh[pos] = Data { some_data: count };
count += 1;
}
sh
}
fn generate_bounding_box(
rng: &mut SmallRng,
x: u32,
y: u32,
z: u32,
) -> (Vector3<u32>, Vector3<u32>) {
let min = Vector3::new(
rng.random_range(0..(x - 2)),
rng.random_range(0..(y - 2)),
rng.random_range(0..(z - 2)),
);
let max = Vector3::new(
rng.random_range(min.x..x),
rng.random_range(min.y..y),
rng.random_range(min.z..z),
);
if min.x > max.x || min.y > max.y || min.z > max.z {
panic!("Generated volume is not in this Universe");
}
(min, max)
}
fn bench_get_filled_data(sh: &SpatialHashGrid<Data>, min: Vector3<u32>, max: Vector3<u32>) {
for (c, elem) in sh.iter_cubes(min, max) {
black_box(c);
black_box(elem);
}
}
fn bench_modify_filled_data(sh: &mut SpatialHashGrid<Data>, min: Vector3<u32>, max: Vector3<u32>) {
for (c, idx, elem) in sh.iter_cubes_mut(min, max) {
elem.some_data += c.x;
black_box(idx);
}
}
pub fn bench_get_data_if_there(c: &mut Criterion) {
let mut rng = SmallRng::seed_from_u64(42);
let mut group = c.benchmark_group("lookups");
for size in [5u32, 10, 20] {
group.bench_with_input(
criterion::BenchmarkId::from_parameter(size),
&size,
|b, &size| {
let (x, y, z) = (size, size, size);
let spatial = create_and_fill(x, y, z);
b.iter(|| {
let (min, max) = generate_bounding_box(&mut rng, x, y, z);
bench_get_filled_data(&spatial, min, max);
})
},
);
}
drop(group);
let mut group = c.benchmark_group("edits");
for size in [5u32, 10, 20] {
group.bench_with_input(
criterion::BenchmarkId::from_parameter(size),
&size,
|b, &size| {
let (x, y, z) = (size, size, size);
let mut spatial = create_and_fill(x, y, z);
b.iter(|| {
let (min, max) = generate_bounding_box(&mut rng, x, y, z);
bench_modify_filled_data(&mut spatial, min, max);
black_box(&spatial);
})
},
);
}
}
pub fn bench_fill_data(c: &mut Criterion) {
let mut group = c.benchmark_group("writes");
for size in [5u32, 10, 20] {
group.bench_with_input(
criterion::BenchmarkId::from_parameter(size),
&size,
|b, &size| {
b.iter(|| {
let spatial = create_and_fill(size, size, size);
black_box(spatial);
})
},
);
}
}
criterion_group!(benches, bench_get_data_if_there, bench_fill_data);
criterion_main!(benches);