Skip to content

Write minus sign without a branch - #73

Open
patrick-immometrica wants to merge 1 commit into
dtolnay:masterfrom
patrick-immometrica:signed-branchless
Open

patrick-immometrica wants to merge 1 commit into
dtolnay:masterfrom
patrick-immometrica:signed-branchless

Conversation

@patrick-immometrica

Copy link
Copy Markdown

if self < 0 { offset -= 1; buf[offset].write(b'-'); } turns into a real branch, which mispredicts on input where the signs are mixed. Writing the - unconditionally, one byte in front of the digits, and only moving the start offset for negative numbers avoids that. There is always room for the extra byte, because the magnitude takes at most MAX_STR_LEN - 1 bytes.

Numbers are from an Apple M5 (aarch64). Both versions are linked into one binary, alternating 300 rounds over the same 1024 random values and keeping the min; ns per call. Repeating master against master stays within about ±4%.

input master this PR
i64, random length, random sign 3.733 3.301 −11.6%
i64, random length, positive 3.398 3.306 −2.7%
i64, random length, negative 3.321 3.316 −0.2%
i32, random length, random sign 3.138 2.441 −22.2%
i32, random length, positive 2.355 2.350 −0.2%
i32, 1–3 digits, random sign 2.045 1.531 −25.1%
i8, random 1.272 1.134 −10.8%
i128, random length, random sign 5.671 5.203 −8.3%
i64 0 1.322 0.941 −28.8%
i64::MIN 3.596 3.515 −2.3%
u64, random length (unchanged code) 3.489 3.479 −0.3%

Single-sign input stays the same. I added tests for i64::MAX and -1. There were no tests for a positive value at the type's limit or for a one-digit negative value, which are the two cases an off-by-one in the offset would break.

This touches the same line as #72, so whichever goes in second needs a trivial rebase.

The branch on the sign mispredicts when formatting a mix of positive
and negative values. Write the '-' unconditionally and only move the
start offset for negative values.
@patrick-immometrica
patrick-immometrica marked this pull request as ready for review November 5, 2026 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant