Arithmetic borrows its operands - #92
Merged
Merged
Conversation
Every binary operator on numbers went through one promotion step that folded `bool` into the `int` it is and lifted an `int` to a `float` when the other side was one. That step took both operands by value, so an operator that only reads them was handed two copies: a machine word copied twice for every addition in a loop, and a heap allocation made twice for every addition on a bignum, both thrown away on the next line. The promotion now hands out references. `Num` and `Pair` borrow the integer instead of owning it, and a pair of statics gives a `bool` something to point at, since `Int` owns a boxed bignum in its large variant and so cannot be const promoted. Interleaved against the previous build on the five tier zero benchmarks: 1.33x on int_loop, 1.16x on float_loop, 1.14x on str_ops, 1.04x on branch_dispatch, 1.03x on list_grow, so about 1.09x overall and more than that where the program is mostly arithmetic. The profile no longer mentions the promotion at all. What is at the top of it now is `Object` clone and drop at 29% together, which is the object representation and a job for a later milestone. Output was diffed against CPython 3.14 on the five benchmarks, on a program covering bignum, bool and float mixing across every arithmetic, bitwise, shift and comparison operator, and on the OverflowError, ZeroDivisionError, TypeError and ValueError paths. All byte identical.
Merged
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.
ops::promotewas 11% of the run in the profile taken after #91. It foldsboolinto theintit is and lifts anintto afloatwhen the other side is one, and it was taking both operands by value. An operator only reads the two values it is given, so that was a machine word copied twice for every addition in a loop and a heap allocation made twice for every addition on a bignum, for two values dropped on the next line.NumandPairnow borrow the integer. Aboolneeds something to point at, andIntowns a boxed bignum in its large variant so it cannot be const promoted, hence a pair of statics for the two integers aboolcan be.Numbers
Interleaved against the previous build so machine drift does not land on one side, medians of twelve timed runs each:
About 1.09x overall, and more than that on programs that are mostly arithmetic.
The profile afterwards is
Vm::executeat 45%,Object::cloneat 17%,drop_glue::<Object>at 12%,Int::div_modat 7% andObject::equalsat 5%. The promotion is not in it anywhere. Clone and drop together are 29% and that is the object representation, so it is M2 or M3 work rather than something to shave here.Checking
Output diffed against CPython 3.14 on the five tier zero benchmarks, on a program that mixes bignum,
boolandfloatacross every arithmetic, bitwise, shift and comparison operator, and on theOverflowError,ZeroDivisionError,TypeErrorandValueErrorpaths. Byte identical throughout. 429 tests pass, clippy and rustdoc are clean.