Repository navigation
Optimize int add/sub for wide exact ints #151289
Description
Activity
came out of #150425 but since the JIT is a no go zone for the near future ¯_(ツ)_/¯
- addedtype-featureA feature request or enhancementA feature request or enhancementperformancePerformance or resource usagePerformance or resource usageinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
on Jun 11, 2026 I would prefer if you share results of the pyperformance on this. Micro-benchmarks in #150425 looks impressive, but the pyperformance seems to be not affected (or even shows worse results).
So far, I'm not sure that this optimization worth code complications.
Perhaps, it will be better if we first change PyLong internals to use tagged pointers, it was recently come again in this d.p.o thread:
https://discuss.python.org/t/pylongobject-just-use-gmp/106086/29With this, we will have essentially only two code paths for machine-sized integers and for big integers. Just like now.
ah, my bad @skirpichev, I had the message drafted but it wasn't sent:
(.bench) root@codespaces-1df16c:/workspaces/cpython# .bench/bin/python -m pyperf compare_to baseline.json candidate.json add_compact: Mean +- std dev: [baseline] 251 us +- 20 us -> [candidate] 234 us +- 18 us: 1.07x faster add_wide: Mean +- std dev: [baseline] 505 us +- 42 us -> [candidate] 372 us +- 27 us: 1.36x faster sub_compact: Mean +- std dev: [baseline] 261 us +- 33 us -> [candidate] 238 us +- 19 us: 1.09x faster sub_wide: Mean +- std dev: [baseline] 511 us +- 35 us -> [candidate] 389 us +- 48 us: 1.31x faster chain_wide: Mean +- std dev: [baseline] 1.40 ms +- 0.11 ms -> [candidate] 1.06 ms +- 0.09 ms: 1.32x faster Benchmark hidden because not significant (1): chain_compact Geometric mean: 1.18x fasterPerhaps, it will be better if we first change PyLong internals to use tagged pointers, it was recently come again in this d.p.o thread:
actually I was planning to follow up in the future with that, I believe we can leverage both implementations.
you should consider the benchmarks in #150425 separate and probably irrelevant for the next few months since that touches the tier 2 JIT
I had the message drafted but it wasn't sent
Thanks, but as I said - micro-benchmarks are less interesting.
actually I was planning to follow up in the future with that, I believe we can leverage both implementations.
I'm not sure. If we will use separate representation for machine-sized integers (take look on FLINT's fmpz), I don't think we will have need in a third code path ("wide ints").
CC @tim-one
you should consider the benchmarks in #150425 separate and probably irrelevant for the next few months since that touches the tier 2 JIT
PYTHON_JIT=0 should be relevant, no?
CPython has a fast path for compact integers in binary add/sub, but wide exact ints still go through the generic long arithmetic path even when both operands fit in int64_t.
This issue proposes adding a separate fast path for exact PyLong operands that fit in signed 64-bit integers, while preserving the existing compact-int path.
Suggested implementation:
Motivation:
Benchmark evidence:
Benchmark script used locally:
Linked PRs