From 70e615205ebabcb41feec4ee1a48fb6673fd8dda Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 1 Feb 2019 19:10:42 -0800 Subject: [PATCH] Optimize monotonic conversion a little bit --- geometry/src/clip.rs | 2 +- geometry/src/outline.rs | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/geometry/src/clip.rs b/geometry/src/clip.rs index 221fe571..45e1acac 100644 --- a/geometry/src/clip.rs +++ b/geometry/src/clip.rs @@ -286,7 +286,7 @@ trait ContourClipper where Self::Edge: TEdge { } } - let input = mem::replace(self.contour_mut(), Contour::new()); + let input = self.contour_mut().take(); for mut segment in input.iter() { // Easy cases. match edge.trivially_test_segment(&segment) { diff --git a/geometry/src/outline.rs b/geometry/src/outline.rs index db338ab8..c554b67a 100644 --- a/geometry/src/outline.rs +++ b/geometry/src/outline.rs @@ -178,6 +178,17 @@ impl Contour { Contour { points: vec![], flags: vec![], bounds: Rect::zero() } } + // Replaces this contour with a new one, with arrays preallocated to match `self`. + #[inline] + pub(crate) fn take(&mut self) -> Contour { + let length = self.len() as usize; + mem::replace(self, Contour { + points: Vec::with_capacity(length), + flags: Vec::with_capacity(length), + bounds: Rect::zero(), + }) + } + #[inline] pub fn iter(&self) -> ContourIter { ContourIter { contour: self, index: 1 } @@ -345,7 +356,8 @@ impl Contour { #[inline] pub fn make_monotonic(&mut self) { - let contour = mem::replace(self, Contour::new()); + // TODO(pcwalton): Make monotonic in place? + let contour = self.take(); for segment in MonotonicConversionIter::new(contour.iter()) { self.push_segment(segment); }