add tweakable horizon and benchmark
This commit is contained in:
parent
54655dd971
commit
0ecee89421
2 changed files with 44 additions and 14 deletions
|
@ -14,7 +14,7 @@ use criterion::{criterion_group, criterion_main};
|
||||||
const SEED_1: &[u8; 32] = b"Gv0aHMtHkBGsUXNspGU9fLRuCWkZWHZx";
|
const SEED_1: &[u8; 32] = b"Gv0aHMtHkBGsUXNspGU9fLRuCWkZWHZx";
|
||||||
// const SEED_2: &[u8; 32] = b"km7DO4GeaFZfTcDXVpnO7ZJlgUY7hZiS";
|
// const SEED_2: &[u8; 32] = b"km7DO4GeaFZfTcDXVpnO7ZJlgUY7hZiS";
|
||||||
|
|
||||||
const DEFAULT_NUM_POINTS: usize = 1_000_000;
|
const DEFAULT_NUM_POINTS: usize = 100_000;
|
||||||
|
|
||||||
fn new_index(c: &mut Criterion) {
|
fn new_index(c: &mut Criterion) {
|
||||||
c.bench_function("new index", move |b| {
|
c.bench_function("new index", move |b| {
|
||||||
|
@ -60,8 +60,8 @@ fn update_positions(c: &mut Criterion) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nearest(c: &mut Criterion) {
|
fn nearest_default_horizon(c: &mut Criterion) {
|
||||||
c.bench_function("nearst point", move |b| {
|
c.bench_function("nearst point with default horizon", move |b| {
|
||||||
let points: Vec<_> = create_random_points(DEFAULT_NUM_POINTS, SEED_1)
|
let points: Vec<_> = create_random_points(DEFAULT_NUM_POINTS, SEED_1)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|[x, y]| Point2d { x, y })
|
.map(|[x, y]| Point2d { x, y })
|
||||||
|
@ -71,11 +71,34 @@ fn nearest(c: &mut Criterion) {
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
index.nearest(&points[i]);
|
|
||||||
i += 1;
|
i += 1;
|
||||||
|
index.nearest(&points[i - 1]).is_some()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
criterion_group!(benches, new_index, update_positions, nearest);
|
fn nearest_short_horizon(c: &mut Criterion) {
|
||||||
|
c.bench_function("nearst point with short horizon", move |b| {
|
||||||
|
let points: Vec<_> = create_random_points(DEFAULT_NUM_POINTS, SEED_1)
|
||||||
|
.into_iter()
|
||||||
|
.map(|[x, y]| Point2d { x, y })
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let index = Spindex2d::new(&points).with_horizon(20);
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
b.iter(|| {
|
||||||
|
i += 1;
|
||||||
|
index.nearest(&points[i - 1]).is_some()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group!(
|
||||||
|
benches,
|
||||||
|
new_index,
|
||||||
|
update_positions,
|
||||||
|
nearest_default_horizon,
|
||||||
|
nearest_short_horizon
|
||||||
|
);
|
||||||
criterion_main!(benches);
|
criterion_main!(benches);
|
||||||
|
|
25
src/lib.rs
25
src/lib.rs
|
@ -67,7 +67,7 @@ impl PVal {
|
||||||
pub struct Spindex2d {
|
pub struct Spindex2d {
|
||||||
pub xs: RwLock<Vec<PVal>>,
|
pub xs: RwLock<Vec<PVal>>,
|
||||||
pub ys: RwLock<Vec<PVal>>,
|
pub ys: RwLock<Vec<PVal>>,
|
||||||
len: usize,
|
horizon: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Spindex2d {
|
impl Spindex2d {
|
||||||
|
@ -92,10 +92,11 @@ impl Spindex2d {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let horizon = (len / (10usize.pow(len.ilog10() / 2))).max(50);
|
||||||
let index = Self {
|
let index = Self {
|
||||||
xs: xs.into(),
|
xs: xs.into(),
|
||||||
ys: ys.into(),
|
ys: ys.into(),
|
||||||
len,
|
horizon,
|
||||||
};
|
};
|
||||||
|
|
||||||
index.sort();
|
index.sort();
|
||||||
|
@ -103,6 +104,10 @@ impl Spindex2d {
|
||||||
index
|
index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_horizon(self, horizon: usize) -> Self {
|
||||||
|
Self { horizon, ..self }
|
||||||
|
}
|
||||||
|
|
||||||
/// This method assumes that the points have the same cardinality and order as the points used
|
/// This method assumes that the points have the same cardinality and order as the points used
|
||||||
/// when constructing this index. May panic if the updated points argument is longer than the
|
/// when constructing this index. May panic if the updated points argument is longer than the
|
||||||
/// original points.
|
/// original points.
|
||||||
|
@ -148,16 +153,18 @@ impl Spindex2d {
|
||||||
let xs = self.xs.read().unwrap();
|
let xs = self.xs.read().unwrap();
|
||||||
let ys = self.ys.read().unwrap();
|
let ys = self.ys.read().unwrap();
|
||||||
|
|
||||||
let mut nxs = HashMap::with_capacity(100);
|
let len = xs.len();
|
||||||
let mut nys = HashMap::with_capacity(100);
|
let horizon = self.horizon;
|
||||||
|
let mut nxs = HashMap::with_capacity(horizon * 2);
|
||||||
|
let mut nys = HashMap::with_capacity(horizon * 2);
|
||||||
thread::scope(|s| {
|
thread::scope(|s| {
|
||||||
s.spawn(|| {
|
s.spawn(|| {
|
||||||
let p = PVal::new(0, x);
|
let p = PVal::new(0, x);
|
||||||
let nx = match xs.binary_search(&p) {
|
let nx = match xs.binary_search(&p) {
|
||||||
Ok(i) | Err(i) => i,
|
Ok(i) | Err(i) => i,
|
||||||
};
|
};
|
||||||
let start = nx.saturating_sub(50);
|
let start = nx.saturating_sub(horizon);
|
||||||
let end = (nx + (50)).min(self.len);
|
let end = (nx + horizon).min(len);
|
||||||
for p in xs[start..end].iter() {
|
for p in xs[start..end].iter() {
|
||||||
nxs.insert(p.point_index(), p.val());
|
nxs.insert(p.point_index(), p.val());
|
||||||
}
|
}
|
||||||
|
@ -168,14 +175,14 @@ impl Spindex2d {
|
||||||
let ny = match ys.binary_search(&p) {
|
let ny = match ys.binary_search(&p) {
|
||||||
Ok(i) | Err(i) => i,
|
Ok(i) | Err(i) => i,
|
||||||
};
|
};
|
||||||
let start = ny.saturating_sub(50);
|
let start = ny.saturating_sub(horizon);
|
||||||
let end = (ny + 50).min(self.len);
|
let end = (ny + horizon).min(len);
|
||||||
for p in ys[start..end].iter() {
|
for p in ys[start..end].iter() {
|
||||||
nys.insert(p.point_index(), p.val());
|
nys.insert(p.point_index(), p.val());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
let mut points = Vec::with_capacity(100);
|
let mut points = Vec::with_capacity(horizon * 2);
|
||||||
for (id, xval) in nxs.into_iter() {
|
for (id, xval) in nxs.into_iter() {
|
||||||
if let Some(&yval) = nys.get(&id) {
|
if let Some(&yval) = nys.get(&id) {
|
||||||
points.push(Point2d::new(xval, yval));
|
points.push(Point2d::new(xval, yval));
|
||||||
|
|
Loading…
Reference in a new issue