use rand::{Rng, SeedableRng}; use rand_hc::Hc128Rng; use autobats::geom::Point; use criterion::{criterion_group, criterion_main, Criterion}; use rstar::{RStarInsertionStrategy, RTree, RTreeParams}; const SEED_1: &[u8; 32] = b"Gv0aHMtHkBGsUXNspGU9fLRuCWkZWHZx"; const SEED_2: &[u8; 32] = b"km7DO4GeaFZfTcDXVpnO7ZJlgUY7hZiS"; struct Params; impl RTreeParams for Params { const MIN_SIZE: usize = 2; const MAX_SIZE: usize = 30; const REINSERTION_COUNT: usize = 1; type DefaultInsertionStrategy = RStarInsertionStrategy; } const DEFAULT_BENCHMARK_TREE_SIZE: usize = 50_000; fn bulk_load_baseline(c: &mut Criterion) { c.bench_function("bulk load baseline", move |b| { let points: Vec<_> = create_random_points(DEFAULT_BENCHMARK_TREE_SIZE, SEED_1); b.iter(|| { RTree::<_, Params>::bulk_load_with_params(points.clone()); }); }); } fn bulk_load_comparison(c: &mut Criterion) { c.bench_function("insert sequential", |b| { let points: Vec<_> = create_random_points(DEFAULT_BENCHMARK_TREE_SIZE, SEED_1); b.iter(move || { let mut rtree = rstar::RTree::new(); for point in &points { rtree.insert(*point); } }); }); } fn tree_creation_quality(c: &mut Criterion) { const SIZE: usize = 100_000; let points: Vec<_> = create_random_points(SIZE, SEED_1); let tree_bulk_loaded = RTree::<_, Params>::bulk_load_with_params(points.clone()); let mut tree_sequential = RTree::new(); for point in &points { tree_sequential.insert(*point); } let query_points = create_random_points(100_000, SEED_2); let query_points_cloned_1 = query_points.clone(); c.bench_function("bulk load quality", move |b| { b.iter(|| { for query_point in &query_points { tree_bulk_loaded.nearest_neighbor(query_point).unwrap(); } }) }) .bench_function("sequential load quality", move |b| { b.iter(|| { for query_point in &query_points_cloned_1 { tree_sequential.nearest_neighbor(query_point).unwrap(); } }); }); } fn range_query(c: &mut Criterion) { const SIZE: usize = 50_000; let points: Vec<_> = create_random_points(SIZE, SEED_1); let tree = RTree::<_, Params>::bulk_load_with_params(points.clone()); c.bench_function("range query", move |b| { let d = 30.0f32.powi(2); let mut i = 0; b.iter(|| { let q = &points[i]; i = (i + 1) % SIZE; tree.locate_within_distance(*q, d) }) }); } criterion_group!( benches, //bulk_load_baseline, // bulk_load_comparison, // tree_creation_quality, range_query ); criterion_main!(benches); fn create_random_points(num_points: usize, seed: &[u8; 32]) -> Vec { let mut rng = Hc128Rng::from_seed(*seed); let r = (-10_000.0)..=10_000.0; (0..num_points) .map(|_| Point::new(rng.random_range(r.clone()), rng.random_range(r.clone()))) .collect() }