-
-
Notifications
You must be signed in to change notification settings - Fork 32k
gh-100726: optimize construction of range object for medium sized integers #100727
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
Conversation
Could you try this using |
@mdickinson The The Benchmark results Main:
This PR:
Branch using
The benchmark of I am fine with accepting a minor slowdown for the uncommon case, although perhaps there are more cases to consider than I included in the benchmark. Which cases would |
Using a IOW, thinking of the range implementation as a client user of the PyLong implementation, what that client needs is a way to say, efficiently, "tell me whether this object (which I already know is a PyLongObject) fits in a C long, and if so, give me its value as a C long". It's that information about digits, twodigits, medium values, number of bits per digit, etc., that I think we should keep encapsulated within the long implementation - it shouldn't be relevant to users of that implementation. If it starts leaking into other parts of the codebase, that's going to turn into a maintenance headache whenever the long implementation needs tweaking. If none of the existing public or private long API functions does what we need efficiently (e.g., because it's doing index checks and the like), I'd be open to adding a new function that does answer the "tell me whether this PyLong fits in a C long" question efficiently. |
@mdickinson I refactored the Benchmark of the updated PR against main:
Most test cases are faster, now also the cases with long values that are not medium. The new check |
Thanks for the updates! I should have time to take a proper look this weekend. |
@mdickinson Thanks for reviewing. The refactoring of I created #100810 as a simplified version of this PR. Benchmark:
The simplified version is not as fast as this PR, but still a solid improvement over current main. I have no strong preference for either one of the two. The cases that slowdown compared to main (both this PR and the simplified one) involve very large integers that do not fit into a C long, e.g. |
Thanks for the discussion. I confess that I'm much more comfortable with #100810; I'll continue review there. |
The python
range
object contains code to compute the length from the start, stop and step values. This calculation is performed with PyLong objects which is expensive. This PR adds a fast path for the common case where start, stop and step all fit into a long value.Benchmark results:
Benchmark script
Notes
IS_MEDIUM_VALUE
andmedium_value
have been moved fromlongobject.c
to the internal header files. The names have been kept the same to avoid too many changes. But since they are now visible outsidelongobject.c
we can rename them to_PyLong_IsMediumValue
and_PyLong_MediumValue
.