102 lines
3 KiB
Rust
102 lines
3 KiB
Rust
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<Point> {
|
|
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()
|
|
}
|