Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(python): Improve Series.to_numpy performance for chunked Series that would otherwise be zero-copy #16301

Merged
merged 8 commits into from
May 18, 2024

Conversation

stinodego
Copy link
Member

@stinodego stinodego commented May 17, 2024

Ref #16267

Instead of iterating over the values, we rechunk and create a writable view.

This regressed in #16178 - now we get the best of both worlds with a writable array and only a single, fast copy.

Performance of converting a chunked Series of 50 million float32s:

  • Before: ~60ms
  • After: ~25ms

I added some benchmark tests so that we may catch regressions here in the future.

@github-actions github-actions bot added performance Performance issues or improvements python Related to Python Polars labels May 17, 2024
Copy link

codecov bot commented May 17, 2024

Codecov Report

Attention: Patch coverage is 98.24561% with 1 lines in your changes are missing coverage. Please review.

Project coverage is 80.75%. Comparing base (6d48c11) to head (319d255).
Report is 8 commits behind head on main.

Files Patch % Lines
py-polars/src/to_numpy.rs 98.14% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #16301      +/-   ##
==========================================
- Coverage   80.78%   80.75%   -0.03%     
==========================================
  Files        1393     1393              
  Lines      179362   179455      +93     
  Branches     2921     2922       +1     
==========================================
+ Hits       144894   144919      +25     
- Misses      33965    34033      +68     
  Partials      503      503              

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

@stinodego stinodego marked this pull request as ready for review May 17, 2024 22:31
@ritchie46
Copy link
Member

Nice. I like this approach. :)

I added some benchmark tests so that we may catch regressions here in the future.

Not entirely sure how the codspeed works, but are these tests ran by codspeed?

@stinodego stinodego marked this pull request as draft May 18, 2024 07:54
@stinodego
Copy link
Member Author

Not entirely sure how the codspeed works, but are these tests ran by codspeed?

Yes! You can see it here, 3 new benchmarks:
https://codspeed.io/pola-rs/polars/branches/to-np-copy-chunk

Also, I spotted a problem with this implementation for nested data, going to have another look before putting it in review again.

@ritchie46
Copy link
Member

How does one register them then? A specific folder?

@stinodego
Copy link
Member Author

How does one register them then? A specific folder?

You just have to do @pytest.mark.benchmark. That's all. I made a dedicated benchmark folder because our tests require some data generation utilities and it's nice to have those in one place, but it doesn't have to be in there necessarily.

@stinodego
Copy link
Member Author

I had to add an up-front check whether the Series has the right dtype / nested nulls, otherwise we could rechunk unnecessarily.

Should be good to go now, waiting for CI to turn green 🤞

@stinodego stinodego marked this pull request as ready for review May 18, 2024 12:38
@stinodego stinodego requested a review from orlp as a code owner May 18, 2024 12:38
@ritchie46 ritchie46 merged commit 42795c6 into main May 18, 2024
26 checks passed
@ritchie46 ritchie46 deleted the to-np-copy-chunk branch May 18, 2024 15:30
@c-peters c-peters added the accepted Ready for implementation label May 21, 2024
@rhshadrach-8451
Copy link

I'm seeing this raise in 0.20.27; it did not raise for me in 0.20.26. Is this expected?

pl.concat(
    [
        pl.DataFrame({"a": [1, 1, 2], "b": [2, 3, 4]}),
        pl.DataFrame({"a": [1, 1, 2], "b": [2, 3, 4]}),
    ]
).to_numpy()
# PanicException: source slice length (3) does not match destination slice length (6)

I haven't confirmed it to be from this PR, but looked likely.

@rhshadrach-8451
Copy link

Apologies - jumped the gun here. #16288 looks more likely.

Wouittone pushed a commit to Wouittone/polars that referenced this pull request Jun 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted Ready for implementation performance Performance issues or improvements python Related to Python Polars
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants