Placement in the standard library aside, I think Java needs value types and patterns before a non-throwing version of Math.multiplyExact can be made that achieves the same semantic goals.
switch (Maths.multiplyExact(a, b)) { case Product.of(long result) -> {} case Product.overflow() -> {} } On Fri, Dec 13, 2024 at 8:00 AM Charles Oliver Nutter <head...@headius.com> wrote: > 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 > head...@headius.com >