From 7a0fbc612ff4bf9cce23f87a56713b0b58905740 Mon Sep 17 00:00:00 2001 From: Lionel Sambuc Date: Fri, 18 Oct 2019 20:56:10 +0200 Subject: [PATCH] Removing memory allocations --- src/database/db_core.rs | 2 +- src/database/mod.rs | 10 ++----- src/database/space/axis.rs | 2 +- src/database/space/coordinate_system.rs | 37 ++++++++++++------------- src/database/space/mod.rs | 6 ++-- src/database/space/position.rs | 37 ++++++++++++++++++++++--- src/database/space/shape.rs | 6 ++-- src/database/space_index.rs | 2 +- src/json/model.rs | 2 +- src/main.rs | 8 +++--- 10 files changed, 67 insertions(+), 45 deletions(-) diff --git a/src/database/db_core.rs b/src/database/db_core.rs index e800946..deb9146 100644 --- a/src/database/db_core.rs +++ b/src/database/db_core.rs @@ -12,7 +12,7 @@ pub struct CoreQueryParameters<'a> { pub output_space: Option<&'a str>, pub threshold_volume: Option, pub view_port: &'a Option<(Vec, Vec)>, - pub resolution: Option>, + pub resolution: &'a Option>, } impl CoreQueryParameters<'_> { diff --git a/src/database/mod.rs b/src/database/mod.rs index 587faa5..91c4ddc 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -178,10 +178,7 @@ impl DataBase { } // Lookup a space within the reference spaces registered - pub fn space(&self, name: S) -> Result<&Space, String> - where - S: Into, - { + pub fn space(&self, name: &str) -> Result<&Space, String> { let name = name.into(); if &name == space::Space::universe().name() { Ok(space::Space::universe()) @@ -198,10 +195,7 @@ impl DataBase { } // Lookup a dataset within the datasets registered - pub fn core(&self, name: S) -> Result<&Core, String> - where - S: Into, - { + pub fn core(&self, name: &str) -> Result<&Core, String> { let name = name.into(); let r = self.cores.find(&name); diff --git a/src/database/space/axis.rs b/src/database/space/axis.rs index 0192bdf..b6a09e4 100644 --- a/src/database/space/axis.rs +++ b/src/database/space/axis.rs @@ -188,7 +188,7 @@ impl Axis { // Apply Unit scaling let d = d * self.measurement_unit.factor(); - Ok(self.unit_vector.clone() * d) + Ok(&self.unit_vector * d) } // Value is expressed on the current Axis, not in absolute coordinates! diff --git a/src/database/space/coordinate_system.rs b/src/database/space/coordinate_system.rs index c76d894..4fb2c5b 100644 --- a/src/database/space/coordinate_system.rs +++ b/src/database/space/coordinate_system.rs @@ -5,7 +5,7 @@ use super::MAX_K; #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub enum CoordinateSystem { - Universe, + Universe { origin: Position }, // Coordinates in Universe, expressed in f64, and in the Universe number of dimensions. AffineSystem { origin: Position, axes: Vec }, } @@ -18,19 +18,16 @@ impl CoordinateSystem { } } - pub fn origin(&self) -> Position { + pub fn origin(&self) -> &Position { match self { - CoordinateSystem::Universe => { - let origin = [0f64; MAX_K].to_vec(); - origin.into() - } - CoordinateSystem::AffineSystem { origin, .. } => origin.clone(), + CoordinateSystem::Universe { origin, .. } => origin, + CoordinateSystem::AffineSystem { origin, .. } => origin, } } pub fn axes(&self) -> Vec { match self { - CoordinateSystem::Universe => { + CoordinateSystem::Universe { .. } => { //FIXME: Generate a CoordinateSystem on the fly or store it as part of the Universe Space? unimplemented!() } @@ -40,7 +37,7 @@ impl CoordinateSystem { pub fn dimensions(&self) -> usize { match self { - CoordinateSystem::Universe => MAX_K, + CoordinateSystem::Universe { .. } => MAX_K, CoordinateSystem::AffineSystem { axes, .. } => axes.len(), } } @@ -50,10 +47,10 @@ impl CoordinateSystem { let mut high = Vec::with_capacity(self.dimensions()); match self { - CoordinateSystem::Universe => { + CoordinateSystem::Universe { .. } => { for _ in 0..self.dimensions() { - low.push(std::f64::MAX); - high.push(std::f64::MIN); + low.push(std::f64::MIN); + high.push(std::f64::MAX); } } CoordinateSystem::AffineSystem { axes, .. } => { @@ -84,16 +81,16 @@ impl CoordinateSystem { // return a position in the current coordinate system. pub fn rebase(&self, position: &Position) -> Result { match self { - CoordinateSystem::Universe => { + CoordinateSystem::Universe { origin } => { // Ensure the coordinates are encoded into F64 variants of // coordinates by forcing an addition to the origin position // which is expressed as F64 variants. The addition will convert // to F64 automatically. - Ok(self.origin().clone() + position.clone()) + Ok(origin + position) } CoordinateSystem::AffineSystem { origin, axes } => { let dimensions = axes.len(); - let translated = position.clone() - origin.clone(); + let translated = position - origin; let mut rebased = Vec::with_capacity(dimensions); for a in axes.iter().take(dimensions) { @@ -110,16 +107,16 @@ impl CoordinateSystem { // return a position in Universe coordinates. pub fn absolute_position(&self, position: &Position) -> Result { match self { - CoordinateSystem::Universe => { + CoordinateSystem::Universe { origin } => { // Ensure the coordinates are encoded into F64 variants of // coordinates by forcing an addition to the origin position // which is expressed as F64 variants. The addition will convert // to F64 automatically. - Ok(self.origin().clone() + position.clone()) + Ok(origin + position) } CoordinateSystem::AffineSystem { axes, .. } => { // Start from the base origin. - let mut rebased = self.origin(); + let mut rebased = self.origin().clone(); // Convert to Universe coordinates for k in 0..axes.len() { @@ -138,7 +135,7 @@ impl CoordinateSystem { let mut encoded = vec![]; match self { - CoordinateSystem::Universe => { + CoordinateSystem::Universe { .. } => { assert_eq!(position.len(), MAX_K); for c in position { encoded.push(Coordinate::CoordinateF64(*c)); @@ -161,7 +158,7 @@ impl CoordinateSystem { let mut decoded = vec![]; match self { - CoordinateSystem::Universe => { + CoordinateSystem::Universe { .. } => { assert_eq!(position.dimensions(), MAX_K); for c in 0..position.dimensions() { decoded.push(position[c].into()); diff --git a/src/database/space/mod.rs b/src/database/space/mod.rs index 27c5329..e0aa203 100644 --- a/src/database/space/mod.rs +++ b/src/database/space/mod.rs @@ -20,7 +20,9 @@ pub const MAX_K: usize = 3; lazy_static! { static ref UNIVERSE: Space = Space { name: "Universe".into(), - system: CoordinateSystem::Universe, + system: CoordinateSystem::Universe { + origin: [0f64; MAX_K].to_vec().into() + }, }; } @@ -53,7 +55,7 @@ impl Space { &self.name } - pub fn origin(&self) -> Position { + pub fn origin(&self) -> &Position { self.system.origin() } diff --git a/src/database/space/position.rs b/src/database/space/position.rs index 44081d5..bad8725 100644 --- a/src/database/space/position.rs +++ b/src/database/space/position.rs @@ -67,19 +67,17 @@ impl Position { // Unit / Normalized vector from self. pub fn unit(&self) -> Self { - self.clone() * (1f64 / self.norm()) + self * (1f64 / self.norm()) } // This multiplies self^T with other, producing a scalar value pub fn dot_product(&self, other: &Self) -> f64 { assert_eq!(self.dimensions(), other.dimensions()); - let point = self.clone(); - let other = other.clone(); let mut product = 0f64; for k in 0..self.dimensions() { - product += (point[k] * other[k]).f64(); + product += (self[k] * other[k]).f64(); } product @@ -190,6 +188,22 @@ impl Add for Position { } } +impl Add for &Position { + type Output = Position; + + fn add(self, rhs: Self) -> Self::Output { + let dimensions = self.dimensions(); + assert_eq!(dimensions, rhs.dimensions()); + let mut v = Vec::with_capacity(dimensions); + + for k in 0..dimensions { + v.push(self[k] + rhs[k]); + } + + v.into() + } +} + impl AddAssign for Position { fn add_assign(&mut self, rhs: Self) { let dimensions = self.dimensions(); @@ -247,6 +261,21 @@ impl Mul for Position { } } +impl Mul for &Position { + type Output = Position; + + fn mul(self, rhs: f64) -> Self::Output { + let dimensions = self.dimensions(); + let mut v = Vec::with_capacity(dimensions); + + for k in 0..dimensions { + v.push(self[k] * rhs); + } + + v.into() + } +} + // Scalar product impl MulAssign for Position { fn mul_assign(&mut self, rhs: f64) { diff --git a/src/database/space/shape.rs b/src/database/space/shape.rs index 7f85616..990103a 100644 --- a/src/database/space/shape.rs +++ b/src/database/space/shape.rs @@ -78,8 +78,8 @@ impl Shape { for _ in 0..dimensions { vr.push(*radius); } - let vr: Position = vr.into(); - (center.clone() - vr.clone(), center.clone() + vr) + let vr: &Position = &vr.into(); + (center - vr, center + vr) } Shape::BoundingBox(lower, higher) => (lower.clone(), higher.clone()), } @@ -188,7 +188,7 @@ impl Shape { let positions = Shape::gen(&lower, &higher) .into_iter() - .filter(|p| (p.clone() - center.clone()).norm() <= radius) + .filter(|p| (p - center).norm() <= radius) .collect(); Ok(positions) diff --git a/src/database/space_index.rs b/src/database/space_index.rs index 46fdb42..396559b 100644 --- a/src/database/space_index.rs +++ b/src/database/space_index.rs @@ -215,7 +215,7 @@ impl SpaceIndex { let results = self .find_range(&lower, &higher) .into_iter() - .filter(|p| (p.position().clone() - center.clone()).norm() <= radius.f64()) + .filter(|p| (p.position() - center).norm() <= radius.f64()) .collect(); Ok(results) diff --git a/src/json/model.rs b/src/json/model.rs index af6e54a..0a68062 100644 --- a/src/json/model.rs +++ b/src/json/model.rs @@ -110,7 +110,7 @@ impl From<&space::Space> for Space { Space { name: space.name().clone(), - origin: space.origin().into(), + origin: space.origin().clone().into(), axes, } } diff --git a/src/main.rs b/src/main.rs index 9570715..a9dd88b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,7 +41,7 @@ fn main() { output_space: None, threshold_volume: Some(std::f64::MAX), view_port: &None, - resolution: None, + resolution: &None, }; let r = core.get_by_id(&c, id).unwrap(); println!("get_by_id {}: {}", id, r.len()); @@ -52,7 +52,7 @@ fn main() { output_space: None, threshold_volume: Some(0.0), view_port: &None, - resolution: None, + resolution: &None, }; let r = core.get_by_id(&c, id).unwrap(); println!("get_by_id {}: {}", id, r.len()); @@ -63,7 +63,7 @@ fn main() { output_space: None, threshold_volume: Some(std::f64::MAX), view_port: &None, - resolution: None, + resolution: &None, }; let r = core.get_by_label(&c, id).unwrap(); println!("get_by_label {}: {}", id, r.len()); @@ -81,7 +81,7 @@ fn main() { output_space: None, threshold_volume: Some(0.0), view_port: &None, - resolution: None, + resolution: &None, }; let r = core.get_by_shape(&c, &shape, "std").unwrap(); println!("get_by_shape {:?}: {}", shape, r.len());