Repository navigation
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
1 similar comment
This comment was marked as resolved.
This comment was marked as resolved.
skirpichev
left a comment
There was a problem hiding this comment.
As I said in the issue thread, I'm not sure if this worth code complications.
Other than this, few remarks:
- Probably, you should split this pr into several. For instance, separate freelists addition looks unrelated.
- I don't think you should add benchmark script to the sources. Just include this code in pr description, for example.
sure, I'll revert and update the numbers, though I think @peendebak mentioned he had a independent freelist PR somewhere so I'll just drop mine entirely.
sure,though it's standard practices to have a |
|
Do not click the "Update branch" button without a good reason because it notifies everyone watching the PR that there are new changes, when there are not, and it uses up limited CI resources. |
|
I don't see any speedup, and in fact see a significant slowdown on the bigint path: The benchmark scripts in the original issue is not really measuring the operation I feel, so I modified it: |
|
There’s a small bug in the benchmark script in that comment: the two subtraction cases are still doing def bench_sub_compact(loops):
...
for _ in it:
a + b
def bench_sub_wide(loops):
...
for _ in it:
a + bThose should be |
|
I am not a domain expert here, so unfortunately I can't do a thorough review. 1 Footnotes
|
|
I can't add something new, beyond my previous post in the issue thread. |
|
This PR is stale because it has been open for 90 days with no activity. |
|
This introduces branching in the There is also problem with the implementation: ReproducerThe speedup is genuine though: the fallback for non-specialized code is really slower. I would be interested to know whether we can somehow specialize for the compact case, but if failing we can specialize for the multi-digit case. That would be beneficial also for other operations with ints. |
|
Thanks for the reproducer, confirmed. On a 30-bit PGO+LTO build with The root cause is what you described: Also, apologies for the confusion in my earlier reply: I said I'd narrowed this to the int64 path, but what's pushed is the shrink-subtract specialization. Please ignore that comment. I'm reworking it along the lines you suggested: leave the compact specializations exactly as they are on main, and handle the multi-digit case separately. The simplest version I have uses Numbers: wall-clock microbenchmarks on a cloud VM (isolated cores,
So on this base the rework saves 26–58 instructions per wide add/sub, and compact ops are unchanged within noise. Rebased on current main (7dbc797), it saves 30–39 instructions per wide add/sub (~10–12%) in all three configurations, JIT included, again with compact ops unchanged. This PR only helps the 2-digit shrinking case and is 46 instructions worse on 3-digit shrinking without the JIT, which is another reason to drop it. On pyperformance (LTO-only builds, no PGO, one run each, pinned to an isolated core) there's no measurable change. The geometric mean comes out at 1.03x faster, but benchmarks with no wide-int arithmetic moved ±10–20% in both directions (e.g. I'll open the rework as a new PR and close this one, since the approach is different enough. |
|
Closing in favour of #159688, which handles the multi-digit case via |
This specializes exact
intsubtraction for a narrow but useful case: on 30-bit-digit builds, when both operands are non-compact 2- or 3-digitPyLongobjects with the same sign and top digit, subtraction often shrinks the result. The specialized path computes that result directly instead of using generic long subtraction.This does not add a general wide-integer fast path, and compact subtraction remains on its existing path. Non-matching operands deopt/fall back to the existing implementation.
On an Ubuntu x86-64 host (GCC 15.2, 8 logical CPUs), corrected
pyperfmeasurements were:The compact, non-shrinking, and addition differences were not statistically significant in this run.
A representative eight-benchmark
pyperformancesubset showed no significant geometric-mean change.