diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index 1a016d7..2c844a4 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -1,5 +1,8 @@ use std::{ - sync::{Arc, RwLock}, + sync::{ + atomic::{AtomicU64, AtomicUsize, Ordering::Relaxed}, + Arc, RwLock, + }, thread, }; @@ -8,21 +11,15 @@ struct Point2d { y: f64, } -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -struct PointRef2d { - x: usize, - y: usize, -} - -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Default)] struct PVal { point: usize, - val: f64, + val: AtomicU64, } impl PartialEq for PVal { fn eq(&self, other: &Self) -> bool { - self.val == other.val + self.val.load(Relaxed) == other.val.load(Relaxed) } } @@ -30,7 +27,9 @@ impl Eq for PVal {} impl PartialOrd for PVal { fn partial_cmp(&self, other: &Self) -> Option { - self.val.partial_cmp(&other.val) + let a = f64::from_bits(self.val.load(Relaxed)); + let b = f64::from_bits(other.val.load(Relaxed)); + a.partial_cmp(&b) } } @@ -41,33 +40,37 @@ impl Ord for PVal { } struct Spindex2d { - points: Arc>>, - xs: Arc>>>, - ys: Arc>>>, + xpoints: Arc>, + ypoints: Arc>, + xs: Arc>>, + ys: Arc>>, } impl Spindex2d { pub fn new(points: &[Point2d]) -> Self { - let mut ps = Vec::with_capacity(points.len()); + let mut xpoints = Vec::with_capacity(points.len()); + let mut ypoints = Vec::with_capacity(points.len()); let mut xs = Vec::with_capacity(points.len()); let mut ys = Vec::with_capacity(points.len()); for (i, point) in points.iter().enumerate() { let x = PVal { point: i, - val: point.x, + val: AtomicU64::new(point.x.to_bits()), }; - xs.push(x.into()); + xs.push(x); let y = PVal { point: i, - val: point.y, + val: AtomicU64::new(point.y.to_bits()), }; - ys.push(y.into()); - let p = PointRef2d { x: i, y: i }; - ps.push(p.into()); + ys.push(y); + + xpoints.push(AtomicUsize::new(i)); + ypoints.push(AtomicUsize::new(i)); } let index = Self { - points: ps.into(), + xpoints: xpoints.into(), + ypoints: ypoints.into(), xs: Arc::new(RwLock::new(xs)), ys: Arc::new(RwLock::new(ys)), }; @@ -81,53 +84,48 @@ impl Spindex2d { /// when constructing this index. May panic if the updated points argument is longer than the /// original points. pub fn update(&self, points: &[Point2d]) { - todo!() + let mut xs = self.xs.write().unwrap(); + let mut ys = self.ys.write().unwrap(); + for (i, point) in points.iter().enumerate() { + let xi = self.xpoints[i].load(Relaxed); + let yi = self.ypoints[i].load(Relaxed); + let x = point.x.to_bits(); + let x = PVal { + point: i, + val: x.into(), + }; + xs[xi] = x; + + let y = point.y.to_bits(); + let y = PVal { + point: i, + val: y.into(), + }; + ys[yi] = y; + } + self.sort(); } fn sort(&self) { let xs = self.xs.clone(); + let points = self.xpoints.clone(); let xhandle = thread::spawn(move || { let mut xs = xs.write().unwrap(); - xs.sort_unstable_by(|a, b| { - let a = a.read().unwrap(); - let b = b.read().unwrap(); - a.cmp(&b) - }); - }); - - let ys = self.ys.clone(); - let yhandle = thread::spawn(move || { - let mut ys = ys.write().unwrap(); - ys.sort_unstable_by(|a, b| { - let a = a.read().unwrap(); - let b = b.read().unwrap(); - a.cmp(&b) - }); - }); - - xhandle.join().unwrap(); - yhandle.join().unwrap(); - - let xs = self.xs.clone(); - let points = self.points.clone(); - let xhandle = thread::spawn(move || { - let xs = xs.read().unwrap(); + xs.sort_unstable(); for (i, x) in xs.iter().enumerate() { - let x = x.read().unwrap(); let p = x.point; - points[p].write().unwrap().x = i; + points[p].store(i, Relaxed); } }); let ys = self.ys.clone(); - let points = self.points.clone(); + let points = self.ypoints.clone(); let yhandle = thread::spawn(move || { - let ys = ys.read().unwrap(); - + let mut ys = ys.write().unwrap(); + ys.sort_unstable(); for (i, y) in ys.iter().enumerate() { - let y = y.read().unwrap(); let p = y.point; - points[p].write().unwrap().y = i; + points[p].store(i, Relaxed); } }); @@ -185,11 +183,16 @@ fn update_positions(c: &mut Criterion) { let index = Spindex2d::new(&points); let mut round = 0; - b.iter(|| todo!()); + b.iter(|| { + if round % 2 == 0 { + index.update(&jitters); + } else { + index.update(&points); + } + round += 1; + }); }); } -//fn reuse_index(_c: &mut Criterion) {} - criterion_group!(benches, new_index); criterion_main!(benches);