From 8af989e2e52aa6ecb2ed65b60923949d355c88e9 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Wed, 5 Nov 2025 00:35:01 +0200 Subject: [PATCH 1/2] perf: override `ArrayIter` default impl for `nth`, `nth_back`, `last` and `count` --- arrow-array/src/iterator.rs | 49 ++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/arrow-array/src/iterator.rs b/arrow-array/src/iterator.rs index e72b259ef049..05e0d410aa96 100644 --- a/arrow-array/src/iterator.rs +++ b/arrow-array/src/iterator.rs @@ -56,7 +56,7 @@ impl ArrayIter { /// create a new iterator pub fn new(array: T) -> Self { let len = array.len(); - let logical_nulls = array.logical_nulls(); + let logical_nulls = array.logical_nulls().filter(|x| x.null_count() > 0); ArrayIter { array, logical_nulls, @@ -102,6 +102,35 @@ impl Iterator for ArrayIter { Some(self.current_end - self.current), ) } + + fn nth(&mut self, n: usize) -> Option { + // Check if we can advance to the desired offset + match self.current.checked_add(n) { + // Yes, and still within bounds + Some(new_current) if new_current < self.current_end => { + self.current = new_current; + } + + // Either overflow or would exceed current_end + _ => { + self.current = self.current_end; + return None; + } + } + + self.next() + } + + fn last(mut self) -> Option { + self.next_back() + } + + fn count(self) -> usize + where + Self: Sized, + { + self.len() + } } impl DoubleEndedIterator for ArrayIter { @@ -122,6 +151,24 @@ impl DoubleEndedIterator for ArrayIter { }) } } + + fn nth_back(&mut self, n: usize) -> Option { + // Check if we advance to the one before the desired offset + match self.current_end.checked_sub(n) { + // Yes, and still within bounds + Some(new_offset) if self.current < new_offset => { + self.current_end = new_offset; + } + + // Either underflow or would exceed current + _ => { + self.current = self.current_end; + return None; + } + } + + self.next_back() + } } /// all arrays have known size. From 565fd1f6c5e3667d730dd9eb3592a07425bbc012 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Wed, 5 Nov 2025 00:48:45 +0200 Subject: [PATCH 2/2] add inline to match rust impl --- arrow-array/src/iterator.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arrow-array/src/iterator.rs b/arrow-array/src/iterator.rs index 05e0d410aa96..c281231a2e79 100644 --- a/arrow-array/src/iterator.rs +++ b/arrow-array/src/iterator.rs @@ -103,6 +103,7 @@ impl Iterator for ArrayIter { ) } + #[inline] fn nth(&mut self, n: usize) -> Option { // Check if we can advance to the desired offset match self.current.checked_add(n) { @@ -121,10 +122,12 @@ impl Iterator for ArrayIter { self.next() } + #[inline] fn last(mut self) -> Option { self.next_back() } + #[inline] fn count(self) -> usize where Self: Sized, @@ -152,6 +155,7 @@ impl DoubleEndedIterator for ArrayIter { } } + #[inline] fn nth_back(&mut self, n: usize) -> Option { // Check if we advance to the one before the desired offset match self.current_end.checked_sub(n) {