Skip to content

Commit e4d724e

Browse files
committed
Improve rows iterator performance
Using `chunks_exact` avoids the inclusion of bounds checks in the generated assembly, leading to better optimization.
1 parent cc73787 commit e4d724e

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

src/plane.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,31 +137,35 @@ where
137137
#[inline]
138138
#[must_use]
139139
pub fn rows(&self) -> impl DoubleEndedIterator<Item = &[T]> + ExactSizeIterator {
140-
let origin = self.data_origin();
140+
let origin = self.geometry.stride.get() * self.geometry.pad_top;
141141
// SAFETY: The plane creation interface ensures the data is large enough
142142
let visible_data = unsafe { self.data.get_unchecked(origin..) };
143143
visible_data
144-
.chunks(self.geometry.stride.get())
144+
.chunks_exact(self.geometry.stride.get())
145145
.take(self.geometry.height.get())
146146
.map(|row| {
147+
let start_idx = self.geometry.pad_left;
148+
let end_idx = start_idx + self.geometry.width.get();
147149
// SAFETY: The plane creation interface ensures the data is large enough
148-
unsafe { row.get_unchecked(..self.geometry.width.get()) }
150+
unsafe { row.get_unchecked(start_idx..end_idx) }
149151
})
150152
}
151153

152154
/// Returns a mutable iterator over the visible pixels of each row
153155
/// in the plane, from top to bottom.
154156
#[inline]
155157
pub fn rows_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut [T]> + ExactSizeIterator {
156-
let origin = self.data_origin();
158+
let origin = self.geometry.stride.get() * self.geometry.pad_top;
157159
// SAFETY: The plane creation interface ensures the data is large enough
158160
let visible_data = unsafe { self.data.get_unchecked_mut(origin..) };
159161
visible_data
160-
.chunks_mut(self.geometry.stride.get())
162+
.chunks_exact_mut(self.geometry.stride.get())
161163
.take(self.geometry.height.get())
162164
.map(|row| {
165+
let start_idx = self.geometry.pad_left;
166+
let end_idx = start_idx + self.geometry.width.get();
163167
// SAFETY: The plane creation interface ensures the data is large enough
164-
unsafe { row.get_unchecked_mut(..self.geometry.width.get()) }
168+
unsafe { row.get_unchecked_mut(start_idx..end_idx) }
165169
})
166170
}
167171

0 commit comments

Comments
 (0)