From cbdca1407043aeccd4402c88a5d7daefda3ae5a7 Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers Date: Wed, 29 Jan 2025 10:16:08 +0100 Subject: [PATCH 1/2] Optimize `Iterator::last()` for `PyList` & `PyTuple` --- newsfragments/4878.added.md | 1 + src/types/list.rs | 8 ++++++++ src/types/tuple.rs | 16 ++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 newsfragments/4878.added.md diff --git a/newsfragments/4878.added.md b/newsfragments/4878.added.md new file mode 100644 index 00000000000..040c6d860e5 --- /dev/null +++ b/newsfragments/4878.added.md @@ -0,0 +1 @@ +Optimizes `last` for `BoundListIterator`, `BoundTupleIterator` and `BorrowedTupleIterator` \ No newline at end of file diff --git a/src/types/list.rs b/src/types/list.rs index 76da36d00b9..45a69b93195 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -631,6 +631,14 @@ impl<'py> Iterator for BoundListIterator<'py> { (len, Some(len)) } + #[inline] + fn last(mut self) -> Option + where + Self: Sized, + { + self.next_back() + } + #[inline] #[cfg(all(Py_GIL_DISABLED, not(feature = "nightly")))] fn fold(mut self, init: B, mut f: F) -> B diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 8147b872af5..9880c510aa0 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -375,6 +375,14 @@ impl<'py> Iterator for BoundTupleIterator<'py> { let len = self.len(); (len, Some(len)) } + + #[inline] + fn last(mut self) -> Option + where + Self: Sized, + { + self.next_back() + } } impl DoubleEndedIterator for BoundTupleIterator<'_> { @@ -467,6 +475,14 @@ impl<'a, 'py> Iterator for BorrowedTupleIterator<'a, 'py> { let len = self.len(); (len, Some(len)) } + + #[inline] + fn last(mut self) -> Option + where + Self: Sized, + { + self.next_back() + } } impl DoubleEndedIterator for BorrowedTupleIterator<'_, '_> { From 8bc30f93b7d1166b5ad2be464e08497cd49f6070 Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers Date: Wed, 29 Jan 2025 11:01:44 +0100 Subject: [PATCH 2/2] Optimize `Iterator::count()` for `PyDict`, `PyList`, `PyTuple` & `PySet` --- newsfragments/4878.added.md | 3 ++- src/types/dict.rs | 16 ++++++++++++++++ src/types/frozenset.rs | 8 ++++++++ src/types/list.rs | 8 ++++++++ src/types/set.rs | 8 ++++++++ src/types/tuple.rs | 16 ++++++++++++++++ 6 files changed, 58 insertions(+), 1 deletion(-) diff --git a/newsfragments/4878.added.md b/newsfragments/4878.added.md index 040c6d860e5..0130b2b805b 100644 --- a/newsfragments/4878.added.md +++ b/newsfragments/4878.added.md @@ -1 +1,2 @@ -Optimizes `last` for `BoundListIterator`, `BoundTupleIterator` and `BorrowedTupleIterator` \ No newline at end of file +- Optimizes `last` for `BoundListIterator`, `BoundTupleIterator` and `BorrowedTupleIterator` +- Optimizes `Iterator::count()` for `PyDict`, `PyList`, `PyTuple` & `PySet` \ No newline at end of file diff --git a/src/types/dict.rs b/src/types/dict.rs index 0d2e6ff335f..1d6b477736c 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -534,6 +534,14 @@ impl<'py> Iterator for BoundDictIterator<'py> { (len, Some(len)) } + #[inline] + fn count(self) -> usize + where + Self: Sized, + { + self.len() + } + #[inline] #[cfg(Py_GIL_DISABLED)] fn fold(mut self, init: B, mut f: F) -> B @@ -736,6 +744,14 @@ mod borrowed_iter { let len = self.len(); (len, Some(len)) } + + #[inline] + fn count(self) -> usize + where + Self: Sized, + { + self.len() + } } impl ExactSizeIterator for BorrowedDictIter<'_, '_> { diff --git a/src/types/frozenset.rs b/src/types/frozenset.rs index 954c49b5902..ee9a9b11f1f 100644 --- a/src/types/frozenset.rs +++ b/src/types/frozenset.rs @@ -237,6 +237,14 @@ impl<'py> Iterator for BoundFrozenSetIterator<'py> { fn size_hint(&self) -> (usize, Option) { (self.remaining, Some(self.remaining)) } + + #[inline] + fn count(self) -> usize + where + Self: Sized, + { + self.len() + } } impl ExactSizeIterator for BoundFrozenSetIterator<'_> { diff --git a/src/types/list.rs b/src/types/list.rs index 45a69b93195..20023e0e146 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -631,6 +631,14 @@ impl<'py> Iterator for BoundListIterator<'py> { (len, Some(len)) } + #[inline] + fn count(self) -> usize + where + Self: Sized, + { + self.len() + } + #[inline] fn last(mut self) -> Option where diff --git a/src/types/set.rs b/src/types/set.rs index d5e39ebc83d..aefe45fbd91 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -270,6 +270,14 @@ impl<'py> Iterator for BoundSetIterator<'py> { fn size_hint(&self) -> (usize, Option) { (self.remaining, Some(self.remaining)) } + + #[inline] + fn count(self) -> usize + where + Self: Sized, + { + self.len() + } } impl ExactSizeIterator for BoundSetIterator<'_> { diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 9880c510aa0..1a61a3e39f8 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -376,6 +376,14 @@ impl<'py> Iterator for BoundTupleIterator<'py> { (len, Some(len)) } + #[inline] + fn count(self) -> usize + where + Self: Sized, + { + self.len() + } + #[inline] fn last(mut self) -> Option where @@ -476,6 +484,14 @@ impl<'a, 'py> Iterator for BorrowedTupleIterator<'a, 'py> { (len, Some(len)) } + #[inline] + fn count(self) -> usize + where + Self: Sized, + { + self.len() + } + #[inline] fn last(mut self) -> Option where