Skip to content

perf: Optimise low-level null scans and arg_max for bools (when chunked)#22897

Merged
orlp merged 2 commits intopola-rs:mainfrom
alexander-beedie:perf-first-last-null
May 23, 2025
Merged

perf: Optimise low-level null scans and arg_max for bools (when chunked)#22897
orlp merged 2 commits intopola-rs:mainfrom
alexander-beedie:perf-first-last-null

Conversation

@alexander-beedie
Copy link
Copy Markdown
Collaborator

@alexander-beedie alexander-beedie commented May 23, 2025

Optimisations

Spotted some nice speedups for the lower-level first_not_null and last_non_null validity/bitmap scans while working on #22880; breaking them out as a standalone PR so we can take advantage while deciding on a better API for that one.

So, switching out the following offset calculations...

mask = BitMask::from_bitmap(validity) 
Some(n) = mask.nth_set_bit_idx(0, 0)               // first non-null
Some(n) = mask.nth_set_bit_idx_rev(0, mask.len())  // last non-null

...for (more or less)...

validity.leading_zeros() < validity.len()   // first non-null
validity.trailing_zeros() < validity.len()  // last non-null

...and adjusting the surrounding code slightly allows us to get the required result directly from the validity bitmap without mediating via BitMask and nth_set_bit_idx.

Speedup:

  • These scans get about 3-5x faster (measured by their impact on the performance of the first/last non-null index methods in the originating PR, as compiled with build-dist-release) 🚀

Also:

  • Generalised the single-chunk fast path in arg_max_bool to handle "n" chunks.
  • Added some fast early-exit conditions for .index_of(None), and an associated small parametric test to improve edge-case coverage.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 23, 2025

Codecov Report

Attention: Patch coverage is 91.66667% with 2 lines in your changes missing coverage. Please review.

Project coverage is 80.63%. Comparing base (b50a36e) to head (dc8cd62).
Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
crates/polars-core/src/utils/mod.rs 85.71% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #22897      +/-   ##
==========================================
- Coverage   80.70%   80.63%   -0.08%     
==========================================
  Files        1671     1671              
  Lines      221173   221446     +273     
  Branches     2792     2791       -1     
==========================================
+ Hits       178502   178563      +61     
- Misses      42001    42218     +217     
+ Partials      670      665       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread crates/polars-core/src/utils/mod.rs Outdated
Comment thread crates/polars-ops/src/series/ops/arg_min_max.rs
@orlp orlp merged commit 199e1cd into pola-rs:main May 23, 2025
29 checks passed
@orlp
Copy link
Copy Markdown
Member

orlp commented May 23, 2025

Thanks :)

@alexander-beedie alexander-beedie deleted the perf-first-last-null branch May 23, 2025 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Performance issues or improvements python Related to Python Polars rust Related to Rust Polars

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants