Why the weird summarysize results for Rational{BigInt}

Here is a clue

julia> n = big"3"^100000;

julia> n.alloc
2494

julia> Base.GMP.MPZ.set!(BigInt(), n).alloc
2477

julia> copy(n).alloc
2494

Note that copy(n::BigInt) dispatches to copy(x::Number) = x. There must be a reason for this, even though ismutable(big(1)) is true.

EDIT: If you follow the code for Base.GMP.MPZ.set! you’ll find that it allocates memory for the target based on the size of the source, not the alloc of the source:

julia> n.alloc
2494

julia> n.size
2477
void
mpz_set (mpz_ptr w, mpz_srcptr u)
{
  mp_ptr wp, up;
  mp_size_t usize, size;

  usize = SIZ(u);
  size = ABS (usize);

  wp = MPZ_NEWALLOC (w, size);

  up = PTR(u);

  MPN_COPY (wp, up, size);
  SIZ(w) = usize;
}

EDIT: It’s really here

julia> Rational(n).num.alloc
2494

julia> Rational(n, 1).num.alloc
2477

The two-arg version calls set, which as mentioned above, uses size rather than alloc to determine what to allocate.

And the one-arg version calls Base.unsafe_rational, which does no copy at all. The numerator in the rational is the same object as n.

1 Like