Skip to content

Commit

Permalink
perf: Use sorted flag for (first|last)_non_null (#15050)
Browse files Browse the repository at this point in the history
  • Loading branch information
nameexhaustion committed Mar 14, 2024
1 parent 82932c6 commit 165f579
Showing 1 changed file with 36 additions and 2 deletions.
38 changes: 36 additions & 2 deletions crates/polars-core/src/chunked_array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,50 @@ impl<T: PolarsDataType> ChunkedArray<T> {

/// Get the index of the first non null value in this [`ChunkedArray`].
pub fn first_non_null(&self) -> Option<usize> {
if self.is_empty() {
if self.null_count() == self.len() {
None
}
// We now know there is at least 1 non-null item in the array, and self.len() > 0
else if matches!(
self.is_sorted_flag(),
IsSorted::Ascending | IsSorted::Descending
) {
let out = if unsafe { self.downcast_get_unchecked(0).is_null_unchecked(0) } {
// nulls are all at the start
self.null_count()
} else {
// nulls are all at the end
0
};

Some(out)
} else {
first_non_null(self.iter_validities())
}
}

/// Get the index of the last non null value in this [`ChunkedArray`].
pub fn last_non_null(&self) -> Option<usize> {
last_non_null(self.iter_validities(), self.length as usize)
if self.null_count() == self.len() {
None
}
// We now know there is at least 1 non-null item in the array, and self.len() > 0
else if matches!(
self.is_sorted_flag(),
IsSorted::Ascending | IsSorted::Descending
) {
let out = if unsafe { self.downcast_get_unchecked(0).is_null_unchecked(0) } {
// nulls are all at the start
self.len() - 1
} else {
// nulls are all at the end
self.len() - self.null_count() - 1
};

Some(out)
} else {
last_non_null(self.iter_validities(), self.len())
}
}

/// Get the buffer of bits representing null values
Expand Down

0 comments on commit 165f579

Please sign in to comment.