High cost of failed Math.*Exact calls
Charles Oliver Nutter
headius at headius.com
Thu Dec 12 22:58:32 UTC 2024
Hey folks, I was looking into a performance bug report for JRuby that did a
lot of numeric work (a prime number detector) and ran into a bottleneck due
to our use of Math.multiplyExact.
Basically, the *Exact methods work great as long as you never actually
overflow. If you overflow (too much), the cost of the exception raised
massively outweighs any gains from avoiding the manual overflow check.
I'm wondering two things at this point:
Question one: Do we need to add versions of these methods that don't raise?
Obviously we only have one return value, so the failure case needs to be
communicated a different way. I'm thinking something like
Math.multiplyExact(long a, long b, long failure) that will return the
failure value for either an overflow or if the multiply produced that exact
value. It would mean one value can never be produced through multiplyExact,
but I think that's a tiny cost compared to raising an exception for all
overflows.
Of course you can do two of these in a row with different failure values to
avoid falling back on BigInteger logic, and only 1 result out of 2**63 will
have to multiply twice.
Question two: Am I losing the benefits of *Exact if I use the following
code to "pre-check" for overflow?
long high = Math.multiplyHigh(a, b);
if (high == 0) return Math.multiplyExact(a, b);
return bigIntegerMultiply(a, b);
Until there's a no-throw version of Math.*Exact I may have to go with this
code.
*Charles Oliver Nutter*
*Architect and Technologist*
Headius Enterprises
https://www.headius.com
headius at headius.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20241212/e7f633fb/attachment.htm>
More information about the core-libs-dev
mailing list