-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
455 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,78 @@ | ||
use std::iter::repeat_with; | ||
|
||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
use spatial_bench as sb; | ||
use fastrand::Rng; | ||
use spatial_bench::{ | ||
bosque::BosqueArena, kiddo::KiddoArena, nabo::NaboArena, read_augmented, rstar::RstarArena, | ||
Point3, SpatialArena, | ||
}; | ||
|
||
const N_NEURONS: usize = 1000; | ||
|
||
fn make_arena<S: SpatialArena>(pts: Vec<Vec<Point3>>) -> S { | ||
let mut ar = S::default(); | ||
for p in pts.into_iter() { | ||
ar.add_points(p); | ||
} | ||
ar | ||
} | ||
|
||
fn random_pairs(max: usize, n: usize, rng: &mut Rng) -> Vec<(usize, usize)> { | ||
repeat_with(|| (rng.usize(0..max), rng.usize(0..max))) | ||
.take(n) | ||
.collect() | ||
} | ||
|
||
fn pair_queries<S: SpatialArena>(arena: &S, pairs: &[(usize, usize)]) { | ||
for (q, t) in pairs { | ||
arena.query_target(*q, *t); | ||
} | ||
} | ||
|
||
fn read_augmented_fixed() -> Vec<Vec<Point3>> { | ||
let mut rng = fastrand::Rng::with_seed(1991); | ||
read_augmented(N_NEURONS, &mut rng, 20.0, 1.0) | ||
} | ||
|
||
pub fn bench_construction(c: &mut Criterion) { | ||
let points = read_augmented_fixed(); | ||
|
||
let mut group = c.benchmark_group("construction"); | ||
group.bench_function("bosque", |b| { | ||
b.iter(|| black_box(make_arena::<BosqueArena>(points.clone()))) | ||
}); | ||
group.bench_function("kiddo", |b| { | ||
b.iter(|| black_box(make_arena::<KiddoArena>(points.clone()))) | ||
}); | ||
group.bench_function("nabo", |b| { | ||
b.iter(|| black_box(make_arena::<NaboArena>(points.clone()))) | ||
}); | ||
group.bench_function("rstar", |b| { | ||
b.iter(|| black_box(make_arena::<RstarArena>(points.clone()))) | ||
}); | ||
} | ||
|
||
pub fn bench_queries(c: &mut Criterion) { | ||
let points = read_augmented_fixed(); | ||
let n_pairs = 1_000; | ||
let mut rng = fastrand::Rng::with_seed(1991); | ||
let pairs = random_pairs(points.len(), n_pairs, &mut rng); | ||
let mut group = c.benchmark_group("pairwise query"); | ||
|
||
let ar = make_arena::<BosqueArena>(points.clone()); | ||
group.bench_function("bosque", |b| { | ||
b.iter(|| black_box(pair_queries(&ar, &pairs))) | ||
}); | ||
|
||
let ar = make_arena::<KiddoArena>(points.clone()); | ||
group.bench_function("kiddo", |b| b.iter(|| black_box(pair_queries(&ar, &pairs)))); | ||
|
||
let ar = make_arena::<NaboArena>(points.clone()); | ||
group.bench_function("nabo", |b| b.iter(|| black_box(pair_queries(&ar, &pairs)))); | ||
|
||
pub fn criterion_benchmark(c: &mut Criterion) { | ||
c.bench_function("fib 20", |b| b.iter(|| fibonacci(black_box(20)))); | ||
let ar = make_arena::<RstarArena>(points.clone()); | ||
group.bench_function("rstar", |b| b.iter(|| black_box(pair_queries(&ar, &pairs)))); | ||
} | ||
|
||
criterion_group!(benches, criterion_benchmark); | ||
criterion_group!(benches, bench_construction, bench_queries); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
use crate::{Point3, Precision, SpatialArena}; | ||
|
||
#[derive(Default)] | ||
pub struct BosqueArena { | ||
trees: Vec<Vec<Point3>>, | ||
idxs: Vec<Vec<usize>>, | ||
} | ||
|
||
impl SpatialArena for BosqueArena { | ||
fn add_points(&mut self, mut p: Vec<Point3>) -> usize { | ||
let mut idxs: Vec<_> = (0..(p.len() as u32)).collect(); | ||
bosque::tree::build_tree_with_indices(p.as_mut(), idxs.as_mut()); | ||
let idx = self.len(); | ||
self.trees.push(p); | ||
self.idxs | ||
.push(idxs.into_iter().map(|i| i as usize).collect()); | ||
idx | ||
} | ||
|
||
fn query_target(&self, q: usize, t: usize) -> Vec<(usize, Precision)> { | ||
let tgt = self.trees.get(t).unwrap(); | ||
let tgt_idxs = self.idxs.get(t).unwrap(); | ||
self.trees | ||
.get(q) | ||
.unwrap() | ||
.iter() | ||
.map(|p| { | ||
let (d, idx) = bosque::tree::nearest_one(tgt.as_slice(), p); | ||
(tgt_idxs[idx], d) | ||
}) | ||
.collect() | ||
} | ||
|
||
fn local_query(&self, q: usize, neighborhood: usize) -> Vec<Vec<usize>> { | ||
let t = self.trees.get(q).unwrap(); | ||
let idxs = self.idxs.get(q).unwrap(); | ||
t.iter() | ||
.map(|p| { | ||
bosque::tree::nearest_k(t.as_slice(), p, neighborhood) | ||
.into_iter() | ||
.map(|(_d, i)| idxs[i]) | ||
.collect() | ||
}) | ||
.collect() | ||
} | ||
|
||
fn len(&self) -> usize { | ||
self.trees.len() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
use kiddo::{ImmutableKdTree, SquaredEuclidean}; | ||
|
||
use crate::{Point3, Precision, SpatialArena}; | ||
|
||
#[derive(Default)] | ||
pub struct KiddoArena { | ||
trees: Vec<ImmutableKdTree<Precision, 3>>, | ||
points: Vec<Vec<Point3>>, | ||
} | ||
|
||
impl SpatialArena for KiddoArena { | ||
fn add_points(&mut self, p: Vec<Point3>) -> usize { | ||
let idx = self.len(); | ||
self.trees.push(p.as_slice().into()); | ||
self.points.push(p); | ||
idx | ||
} | ||
|
||
fn query_target(&self, q: usize, t: usize) -> Vec<(usize, Precision)> { | ||
let tgt = self.trees.get(t).unwrap(); | ||
self.points | ||
.get(q) | ||
.unwrap() | ||
.iter() | ||
.map(|p| { | ||
let nn = tgt.nearest_one::<SquaredEuclidean>(p); | ||
(nn.item as usize, nn.distance.sqrt()) | ||
}) | ||
.collect() | ||
} | ||
|
||
fn local_query(&self, q: usize, neighborhood: usize) -> Vec<Vec<usize>> { | ||
let tgt = self.trees.get(q).unwrap(); | ||
self.points | ||
.get(q) | ||
.unwrap() | ||
.iter() | ||
.map(|p| { | ||
tgt.nearest_n::<SquaredEuclidean>(p, neighborhood) | ||
.into_iter() | ||
.map(|nn| nn.item as usize) | ||
.collect() | ||
}) | ||
.collect() | ||
} | ||
|
||
fn len(&self) -> usize { | ||
self.trees.len() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.