From aa71ffd512a2f7334b56e075a1bdb33aa1044bdb Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 5 Dec 2023 08:37:50 -0800 Subject: [PATCH] PERF: `TriangulateSpade` uses Iter, not Vec This is an internal API, so we can safely break the API. Bench output: ``` TriangulateSpade (unconstrained) - small polys time: [8.7534 ms 8.7641 ms 8.7777 ms] change: [-2.6587% -2.1965% -1.7360%] (p = 0.00 < 0.05) Performance has improved. Found 5 outliers among 100 measurements (5.00%) 3 (3.00%) high mild 2 (2.00%) high severe Benchmarking TriangulateSpade (constrained) - small polys: Warming up for 3.0000 s Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 98.7s, or reduce sample count to 10. TriangulateSpade (constrained) - small polys time: [986.61 ms 987.03 ms 987.51 ms] change: [-5.2413% -5.0808% -4.9190%] (p = 0.00 < 0.05) Performance has improved. Found 17 outliers among 100 measurements (17.00%) 7 (7.00%) high mild 10 (10.00%) high severe TriangulateEarcut - small polys time: [6.9938 ms 6.9993 ms 7.0041 ms] change: [-1.3566% -0.9176% -0.5312%] (p = 0.00 < 0.05) Change within noise threshold. Found 12 outliers among 100 measurements (12.00%) 5 (5.00%) low severe 5 (5.00%) low mild 2 (2.00%) high mild TriangulateSpade (unconstrained) - large_poly time: [3.4280 ms 3.4390 ms 3.4521 ms] change: [+0.2922% +0.7947% +1.3032%] (p = 0.00 < 0.05) Change within noise threshold. Found 13 outliers among 100 measurements (13.00%) 7 (7.00%) high mild 6 (6.00%) high severe Benchmarking TriangulateSpade (constrained) - large_poly: Warming up for 3.0000 s Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 178.3s, or reduce sample count to 10. TriangulateSpade (constrained) - large_poly time: [1.7869 s 1.8005 s 1.8178 s] change: [-7.9992% -5.8498% -4.2765%] (p = 0.00 < 0.05) Performance has improved. Found 14 outliers among 100 measurements (14.00%) 5 (5.00%) high mild 9 (9.00%) high severe TriangulateEarcut - large_poly time: [2.2287 ms 2.2346 ms 2.2413 ms] change: [+1.0859% +1.4903% +1.9614%] (p = 0.00 < 0.05) Performance has regressed. Found 14 outliers among 100 measurements (14.00%) 10 (10.00%) high mild 4 (4.00%) high severe ``` --- geo/CHANGES.md | 2 ++ geo/src/algorithm/triangulate_spade.rs | 21 ++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/geo/CHANGES.md b/geo/CHANGES.md index 7a0b1ab8e..0c36437c8 100644 --- a/geo/CHANGES.md +++ b/geo/CHANGES.md @@ -9,6 +9,8 @@ * * Make `SpadeTriangulationConfig` actually configurable * +* PERF: small improvements to TriangulateSpade trait + * ## 0.27.0 diff --git a/geo/src/algorithm/triangulate_spade.rs b/geo/src/algorithm/triangulate_spade.rs index 544c53963..96094a900 100644 --- a/geo/src/algorithm/triangulate_spade.rs +++ b/geo/src/algorithm/triangulate_spade.rs @@ -65,6 +65,9 @@ pub type Triangles = Vec>; // so that we don't leak these weird methods on the public interface. mod private { use super::*; + + pub(crate) type CoordsIter<'a, T> = Box> + 'a>; + pub trait TriangulationRequirementTrait<'a, T> where T: SpadeTriangulationFloat, @@ -76,7 +79,7 @@ mod private { fn lines(&'a self) -> Vec>; /// collect all the coords that are relevant for triangulations from the geometric object that /// should be triangulated - fn coords(&'a self) -> Vec>; + fn coords(&'a self) -> CoordsIter; /// define a predicate that decides if a point is inside of the object (used for constrained triangulation) fn contains_point(&'a self, p: Point) -> bool; @@ -315,8 +318,8 @@ where T: SpadeTriangulationFloat, G: LinesIter<'l, Scalar = T> + CoordsIter + Contains>, { - fn coords(&'a self) -> Vec> { - self.coords_iter().collect::>() + fn coords(&'a self) -> private::CoordsIter { + Box::new(self.coords_iter()) } fn lines(&'a self) -> Vec> { @@ -333,11 +336,11 @@ where impl<'a, T, G> private::TriangulationRequirementTrait<'a, T> for Vec where - T: SpadeTriangulationFloat, + T: SpadeTriangulationFloat + 'a, G: TriangulateSpade<'a, T>, { - fn coords(&'a self) -> Vec> { - self.iter().flat_map(|g| g.coords()).collect::>() + fn coords(&'a self) -> private::CoordsIter { + Box::new(self.iter().flat_map(|g| g.coords())) } fn lines(&'a self) -> Vec> { @@ -351,11 +354,11 @@ where impl<'a, T, G> private::TriangulationRequirementTrait<'a, T> for &[G] where - T: SpadeTriangulationFloat, + T: SpadeTriangulationFloat + 'a, G: TriangulateSpade<'a, T>, { - fn coords(&'a self) -> Vec> { - self.iter().flat_map(|g| g.coords()).collect::>() + fn coords(&'a self) -> private::CoordsIter { + Box::new(self.iter().flat_map(|g| g.coords())) } fn lines(&'a self) -> Vec> {