gh-100687: Reduce frequency of overallocation in x_add() - #158002
Open
eendebakpt wants to merge 1 commit into
Open
eendebakpt wants to merge 1 commit into
eendebakpt wants to merge 1 commit into
Conversation
x_add() allocated a digit for the carry out of the top digit on every call. In most cases that digit is zero and long_normalize() drops it from the digit count, but the allocation keeps its size, so the result uses more memory than its value needs for as long as it lives. Allocate the carry digit only when the top digits of the operands sum to at least PyLong_MASK, the only case in which a carry out of the top digit is possible. When no carry digit was allocated the top digit of the result is at least the top digit of the larger operand, so the result is already normalized and is returned directly. This applies to same-sign additions and opposite-sign subtractions, which go through x_add(); x_sub() is unchanged. Extends PR 100688 by Mark Dickinson, which contributed the size test and the tests. Co-authored-by: Mark Dickinson <dickinsm@gmail.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extends #100688 by @mdickinson.
x_add()allocated a digit for the carry out of the top digit on every call; in most cases that digit is zero. In this PR we avoid the overallocation and the normalize in most of the cases.Memory
Resident bytes per result for a list of one million sums, PGO+LTO build. A dropped digit changes the pymalloc size class every fourth digit count, so only those sizes shrink; the others are unchanged.
Speed
PGO+LTO build. Small and medium additions get faster because the result is returned without
long_normalize(); for 100 digits and more the extra top-digit test shows as 1 to 3% and the saved call no longer matters.a + b, 3 to 10 digits, both operand classesa + b, 10x2 digits(-a) + (-b), 5 digits (same sign, stillx_add())a + b, 100 and 1000 digitsa - b, 5 and 10 digits (x_sub(), control)fib(300)math.factorial(200)Benchmark scripts
Timing:
python bench_xadd.py -o out.json --affinity CPUunder each build, thenpython -m pyperf compare_to --table. Memory:python bench_memory.pyunder each build (thea + brows).Generated with Claude Code