Skip irrelevant fractional truncation scan

perfloop/fast_float · INEFFICIENT ALGORITHM

https://perfloop.ai/t/oss/case_9k6jbbrrax

Verdict

VERIFIED · settled 2026-08-06 · pull request opened as fastfloat/fast_float#402

Hypothesis

`parse_mantissa` reaches this block once per exact-conversion invocation that hits `max_digits` while parsing the integer span. Its first `is_truncated(p, pend)` determines whether any unparsed integer digit is nonzero, but line 289 then evaluates `is_truncated(num.fraction)` through `|=` even when that result is already true. The only consumer is the following `if (truncated)` that selects `round_up_bigint`, so a true integer suffix makes the fractional result unable to change rounding. The helper's source walks eight code units at a time, then a scalar tail, until a nonzero or the end; thus the avoidable delta grows linearly with fractional-tail length F, once per qualifying call. I ran a local GCC 14.2 `-O3` direct A/B probe of the actual function with a 770-digit nonzero integer (double's cap is 769) and a 4 MiB all-zero fraction for 32 calls. Both variants produced the same sink (25920); the current header took 7.44–7.54 ms and the guarded header 0.099–0.121 ms. That is an isolated synthetic probe, not evidence of workload frequency or end-to-end latency, but it shows this compiler did not eliminate the eager scan and that the removed pass can dominate under the stated trigger. A case should benchmark both direct `parse_mantissa` and end-to-end slow exact-conversion inputs while sweeping fractional-tail length and zero/nonzero density, with remaining integer suffixes that are both zero and nonzero; the confirming signal is reduced CPU/time and bytes examined only for the nonzero-integer-suffix condition, with identical conversion and rounding results across boundary and long-input differential cases.

Change to test: At the integer-cap return, retain the integer-suffix `is_truncated(p, pend)` result, but scan `num.fraction` only when that result is false. Replace the compound `|=` with a short-circuiting guard so `round_up_bigint` sees the same OR result while a known-true integer truncation does not traverse an irrelevant fractional suffix.

Where it lives

perfloop/fast_float · include/fast_float/digit_comparison.h

Evidence

direct parse_mantissa: 770-digit integer with a nonzero discarded suffix and a 4 MiB zero fraction · 10 sample pairs

metric baseline candidate paired median change confidence range required result
ns/op 220801 928 −99.6% (−219875) −226131 to −215201 < 0 PASSED

public from_chars exact fallback: 770-digit integer with a nonzero discarded suffix and a 4 MiB zero fraction · 10 sample pairs

metric baseline candidate paired median change confidence range required result
ns/op 2287640 2028719 −11.6% (−265772) −273683 to −246648 < 0 PASSED

public from_chars zero-suffix guardrail: 770-digit integer with a zero discarded suffix and a 4 MiB zero fraction; 17-batch median with a 25 microsecond no-regression budget · 10 sample pairs

metric baseline candidate paired median change confidence range required result
ns/op 2293935 2282803 −0.5% (−10378) −22139 to +10299 ≤ 25000 PASSED

Checks: 4 of 4 passed. Verification: no defect found.

Timeline