Is there an in-place alternative to +=, *=, etc.?

Using += with arbitrary precision integers seems to end up using much more memory (and takes much longer) than the equivalent in-place operator (for my test, I used addeq! from Nemo and add! from Base.GMP.MPZ).

Result:

julia> @time test_mpz(BigInt(5)^200000)
  0.045873 seconds (41 allocations: 354.750 KiB)

julia> @time test_nemo(fmpz(5)^200000)
  0.047201 seconds (38 allocations: 354.664 KiB)

julia> @time test_default(BigInt(5)^200000)
  0.491928 seconds (20.04 k allocations: 554.338 MiB, 0.75% gc time)

Code:

julia> function test_mpz(n)
           output = zero(n)
           for i in 1:10000
               MPZ.add!(output,n)
           end
       end
test_mpz (generic function with 1 method)

julia> function test_nemo(n)
           output = zero(n)
           for i in 1:10000
               addeq!(output, n)
           end
       end
test_nemo (generic function with 1 method)

julia> function test_default(n)
           output = zero(n)
           for i in 1:10000
               output += n
           end
       end
test_default (generic function with 1 method)

This seems to be related to mutability of BigInts; is there no built in +=, *=, etc. operators in Julia that work in-place like mul! in Nemo or Base.GMP.MPZ? (I guess one could argue that the latter is “built in,” but I wanted to know if there were any alternatives). Sorry if this question is basic or has been answered. It seems like in-place ought to be the default behavior for BigInts at least, given the orders of magnitude worse performance in space and time.

1 Like

Maybe something like https://github.com/simonbyrne/InplaceOps.jl could help?

2 Likes