JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.61k stars 5.48k forks source link

mutating APIs for BigInts and BigFloats? #31342

Open StefanKarpinski opened 5 years ago

StefanKarpinski commented 5 years ago

We have Base.GMP.MPZ.add! and other very internal mutating arithmetic operations for BigInts which are used internally within the BigInt implementation to implement faster versions of some operations. #31310 introduces Base.MPFR.nextfloat! and Base.MPFR.prevfloat! as some of the first internal mutating functions for BigFloats. This PR also raises the question of what the API for copying a bignum should be—this is fundamentally part of the same API design question since without mutation there's never any point in copying a bignum.

Should we have a more coherent mutating API for both BigInts and BigFloats? The general guidance for using such a mutating API should probably be that you should only using the mutating operations on bignums when you "own" the bignum in the sense that you're sure that only your code can observe the mutation.

Is this a good idea? Should we avoid this and instead focus on better compiler tech to allow writing non-mutating bignum code and having the compiler reuse bignum objects as necessary? One of the concerns about introducing a mutating API is that needing to support it could potentially prevent such optimizations or make them harder. Perhaps the mutating API could be an experimental API that we might remove in the future.

chethega commented 5 years ago

For experimental API. Compiler optimizations are more important long term, but I think we should do something immediately to make Base.GMP.MPZ more user-friendly. I doubt that the compiler will ever be able to rely on users not using GMP.MPZ inplace operations for correctness, so we should not prevent future optimizations by exposing that.

Something that could work directly (using current lowering) is syntax like a .= b for copying, and a .= b.+c, or with a little more effort a .+= b. The goal would be to find a sensible broadcasting shorthand for every MPZ idiom, and document what works out of the box (it would still be the user's job to break down the code into these operations with a minimum of temporaries, but less annoying to read and write).

tkluck commented 5 years ago

For reference, I wrote InPlace.jl precisely to be able to take advantage of in-place bignum operations.

ultravioletcatastrophe commented 2 years ago

has there been any movement on this issue? the default arithmetic for BigInts being slow seems like a major usability issue for number theorists, etc. I know Nemo implements its own fast arithmetic for Flint multiprecision ints, but it'd be nice to have this functionality as the default behavior

nsajko commented 2 years ago

The MutableArithmetics package might be useful to people who come upon this issue: https://github.com/jump-dev/MutableArithmetics.jl