From 586eda883d5419818f60d6536f9c67b2e7ea2338 Mon Sep 17 00:00:00 2001 From: Jesse Grosjean Date: Mon, 23 Sep 2019 21:30:30 -0400 Subject: [PATCH 1/2] Optimized versions of len, count, and nth for Vector iterators --- src/vector/mod.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/vector/mod.rs b/src/vector/mod.rs index b6728e8..42687fa 100644 --- a/src/vector/mod.rs +++ b/src/vector/mod.rs @@ -1884,6 +1884,20 @@ impl<'a, A: Clone> Iterator for Iter<'a, A> { let remaining = self.back_index - self.front_index; (remaining, Some(remaining)) } + + fn count(self) -> usize { + self.back_index - self.front_index + } + + fn nth(&mut self, n: usize) -> Option { + let len = self.len(); + if n >= len { + None + } else { + self.front_index += n; + self.next() + } + } } impl<'a, A: Clone> DoubleEndedIterator for Iter<'a, A> { @@ -1901,7 +1915,11 @@ impl<'a, A: Clone> DoubleEndedIterator for Iter<'a, A> { } } -impl<'a, A: Clone> ExactSizeIterator for Iter<'a, A> {} +impl<'a, A: Clone> ExactSizeIterator for Iter<'a, A> { + fn len(&self) -> usize { + self.back_index - self.front_index + } +} impl<'a, A: Clone> FusedIterator for Iter<'a, A> {} @@ -1966,6 +1984,21 @@ where let remaining = self.back_index - self.front_index; (remaining, Some(remaining)) } + + fn count(self) -> usize { + self.back_index - self.front_index + } + + fn nth(&mut self, n: usize) -> Option { + let len = self.len(); + if n >= len { + None + } else { + self.front_index += n; + self.next() + } + } + } impl<'a, A> DoubleEndedIterator for IterMut<'a, A> @@ -1986,7 +2019,11 @@ where } } -impl<'a, A: Clone> ExactSizeIterator for IterMut<'a, A> {} +impl<'a, A: Clone> ExactSizeIterator for IterMut<'a, A> { + fn len(&self) -> usize { + self.back_index - self.front_index + } +} impl<'a, A: Clone> FusedIterator for IterMut<'a, A> {} @@ -2635,6 +2672,16 @@ mod test { assert_eq!(&vec[index], item); } assert_eq!(vec.len(), seq.len()); + assert_eq!(vec.iter().count(), seq.iter().count()); + } + + #[test] + #[allow(clippy::iter_nth)] + fn iter_nth(ref vec in vec(i32::ANY, 0..1000)) { + let seq: Vector = Vector::from_iter(vec.iter().cloned()); + assert_eq!(vec.iter().nth(0), seq.iter().nth(0)); + assert_eq!(vec.iter().nth(1), seq.iter().nth(1)); + assert_eq!(vec.iter().nth(vec.len() - 1), seq.iter().nth(vec.len() - 1)); } #[test] From f750850a62520702527d96ef4de129c46ed8fb5f Mon Sep 17 00:00:00 2001 From: Jesse Grosjean Date: Tue, 24 Sep 2019 08:57:49 -0400 Subject: [PATCH 2/2] More work optimizing Vector Iterators to for len, count, nth, and nth_back --- src/vector/mod.rs | 120 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 108 insertions(+), 12 deletions(-) diff --git a/src/vector/mod.rs b/src/vector/mod.rs index 42687fa..d984c47 100644 --- a/src/vector/mod.rs +++ b/src/vector/mod.rs @@ -1881,17 +1881,16 @@ impl<'a, A: Clone> Iterator for Iter<'a, A> { } fn size_hint(&self) -> (usize, Option) { - let remaining = self.back_index - self.front_index; - (remaining, Some(remaining)) + let len = self.len(); + (len, Some(len)) } fn count(self) -> usize { - self.back_index - self.front_index + self.len() } fn nth(&mut self, n: usize) -> Option { - let len = self.len(); - if n >= len { + if n >= self.len() { None } else { self.front_index += n; @@ -1913,6 +1912,15 @@ impl<'a, A: Clone> DoubleEndedIterator for Iter<'a, A> { let focus: &'a mut Focus<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) }; focus.get(self.back_index) } + + fn nth_back(&mut self, n: usize) -> Option { + if n >= self.len() { + None + } else { + self.back_index -= n; + self.next_back() + } + } } impl<'a, A: Clone> ExactSizeIterator for Iter<'a, A> { @@ -1981,24 +1989,22 @@ where } fn size_hint(&self) -> (usize, Option) { - let remaining = self.back_index - self.front_index; - (remaining, Some(remaining)) + let len = self.len(); + (len, Some(len)) } fn count(self) -> usize { - self.back_index - self.front_index + self.len() } fn nth(&mut self, n: usize) -> Option { - let len = self.len(); - if n >= len { + if n >= self.len() { None } else { self.front_index += n; self.next() } } - } impl<'a, A> DoubleEndedIterator for IterMut<'a, A> @@ -2017,6 +2023,15 @@ where let focus: &'a mut FocusMut<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) }; focus.get_mut(self.back_index) } + + fn nth_back(&mut self, n: usize) -> Option { + if n >= self.len() { + None + } else { + self.back_index -= n; + self.next_back() + } + } } impl<'a, A: Clone> ExactSizeIterator for IterMut<'a, A> { @@ -2126,6 +2141,24 @@ impl<'a, A: Clone> Iterator for Chunks<'a, A> { self.front_index = range.end; Some(value) } + + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } + + fn count(self) -> usize { + self.len() + } + + fn nth(&mut self, n: usize) -> Option { + if n >= self.len() { + None + } else { + self.front_index += n; + self.next() + } + } } impl<'a, A: Clone> DoubleEndedIterator for Chunks<'a, A> { @@ -2143,6 +2176,21 @@ impl<'a, A: Clone> DoubleEndedIterator for Chunks<'a, A> { self.back_index = range.start; Some(value) } + + fn nth_back(&mut self, n: usize) -> Option { + if n >= self.len() { + None + } else { + self.back_index -= n; + self.next_back() + } + } +} + +impl<'a, A: Clone> ExactSizeIterator for Chunks<'a, A> { + fn len(&self) -> usize { + self.back_index - self.front_index + } } impl<'a, A: Clone> FusedIterator for Chunks<'a, A> {} @@ -2185,6 +2233,24 @@ impl<'a, A: Clone> Iterator for ChunksMut<'a, A> { self.front_index = range.end; Some(value) } + + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } + + fn count(self) -> usize { + self.len() + } + + fn nth(&mut self, n: usize) -> Option { + if n >= self.len() { + None + } else { + self.front_index += n; + self.next() + } + } } impl<'a, A: Clone> DoubleEndedIterator for ChunksMut<'a, A> { @@ -2202,6 +2268,21 @@ impl<'a, A: Clone> DoubleEndedIterator for ChunksMut<'a, A> { self.back_index = range.start; Some(value) } + + fn nth_back(&mut self, n: usize) -> Option { + if n >= self.len() { + None + } else { + self.back_index -= n; + self.next_back() + } + } +} + +impl<'a, A: Clone> ExactSizeIterator for ChunksMut<'a, A> { + fn len(&self) -> usize { + self.back_index - self.front_index + } } impl<'a, A: Clone> FusedIterator for ChunksMut<'a, A> {} @@ -2681,7 +2762,22 @@ mod test { let seq: Vector = Vector::from_iter(vec.iter().cloned()); assert_eq!(vec.iter().nth(0), seq.iter().nth(0)); assert_eq!(vec.iter().nth(1), seq.iter().nth(1)); - assert_eq!(vec.iter().nth(vec.len() - 1), seq.iter().nth(vec.len() - 1)); + let last_index = seq.len().checked_sub(1).unwrap_or(0); + assert_eq!(vec.iter().nth(last_index), seq.iter().nth(last_index)); + let last_index_plus_one = seq.len(); + assert_eq!(vec.iter().nth(last_index_plus_one), seq.iter().nth(last_index_plus_one)); + } + + #[test] + #[allow(clippy::iter_nth)] + fn iter_nth_back(ref vec in vec(i32::ANY, 0..1000)) { + let seq: Vector = Vector::from_iter(vec.iter().cloned()); + assert_eq!(vec.iter().nth_back(0), seq.iter().nth_back(0)); + assert_eq!(vec.iter().nth_back(1), seq.iter().nth_back(1)); + let last_index = seq.len().checked_sub(1).unwrap_or(0); + assert_eq!(vec.iter().nth_back(last_index), seq.iter().nth_back(last_index)); + let last_index_plus_one = seq.len(); + assert_eq!(vec.iter().nth_back(last_index_plus_one), seq.iter().nth_back(last_index_plus_one)); } #[test]