Compare inline Repr as a DoubleWord in PartialEq#71
Open
DRMacIver wants to merge 3 commits into
Open
Conversation
Repr::eq went through as_sign_slice() == as_sign_slice(), materialising two slice references even for inline (<= DoubleWord) values. Compare directly off the capacity + union instead: a sign or scale (inline vs heap) mismatch is immediately unequal, inline values compare as a single DoubleWord, and same-length heap values compare their word slices. This makes the inline encoding's canonicality load-bearing, so also route Repr::ones through from_buffer: a 128-bit ones value is built as a length-2 buffer and must be promoted to the inline DoubleWord form rather than left heap-encoded, otherwise it would no longer compare equal to its inline counterpart. test_ones (ones(128) == u128::MAX) covers this. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Exercises Repr::eq's inline-DoubleWord path, the sign/scale short-circuits, and the cross-representation canonical equality (ones vs the inline form), rather than relying on incidental coverage from existing eq tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cmpute
requested changes
Jun 3, 2026
| // SAFETY: the bit length has been checked and capacity >= length, | ||
| // so capacity is nonzero and larger than 2 | ||
| unsafe { mem::transmute::<Buffer, Repr>(buffer) } | ||
| // Route through `from_buffer` to canonicalise: a 128-bit ones value |
Owner
There was a problem hiding this comment.
It seems that we can just change the conditions for the branchs above to n <= WORD_BITS_USIZE and n <= DWORD_BITS_USIZE.
| // The encoding is canonical, so a sign or scale (inline vs heap) | ||
| // mismatch is immediately unequal; otherwise compare the words directly | ||
| // instead of materialising slices via `as_sign_slice`. | ||
| let cap_a = self.capacity.get(); |
Owner
There was a problem hiding this comment.
Here I suggest using let (cap_a, sign_) = self.sign_capacity();, then there is no need for let abs_a = cap_a.unsigned_abs();` below.
| } | ||
| // SAFETY: capacity tells us which union variant is live. | ||
| unsafe { | ||
| if inline_a { |
Owner
There was a problem hiding this comment.
Can be even more optimized:
match cap_a {
0..1 => {}, // compare as single words
2 => {}, // compare as double words
_ => {}, // compare as slices
}
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.
Optimisations for comparison, specifically designed to speed up small value comparisons by giving them a fast path. Gives ~30% speedup for eq on integers that are <= 2 words, at a cost of about 1% slowdown for larger integers (should be negligible for genuinely large integers, it's just at the crossover point where comparison is still fast enough that a little bit of extra work is noticeable).
Benchmarks (layout-sampled, K=11)
Wall-clock, dashu-only, vs the merge base, measured under 11 randomised function layouts (
ld64 -order_file) and reported as the median — to average out the ±10% code-placement noise that otherwise swamps these small-value micro-benchmarks. The untouchedubig_mulcontrol reads 0.0% ± 0.0%, confirming a clean run.ubig_eqinline (zero/one/two-word)ubig_eqheap (mid/large)ubig_mul(control)