Skip to content

Commit f8223cd

Browse files
committed
avoid re-allocations in rand(UnitRange(::BigInt)) for some cases
1 parent ed19d36 commit f8223cd

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

base/random.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -492,10 +492,11 @@ for (T, U) in [(UInt8, UInt32), (UInt16, UInt32),
492492
end
493493

494494
immutable RangeGeneratorBigInt <: RangeGenerator
495-
a::BigInt # first
496-
m::BigInt # range length - 1
497-
nlimbs::Int # number of limbs in generated BigInt's
498-
mask::Limb # applied to the highest limb
495+
a::BigInt # first
496+
m::BigInt # range length - 1
497+
nlimbs::Int # number of limbs in generated BigInt's (z ∈ [0, m])
498+
nlimbsmax::Int # max number of limbs for z+a
499+
mask::Limb # applied to the highest limb
499500
end
500501

501502

@@ -506,7 +507,8 @@ function RangeGenerator(r::UnitRange{BigInt})
506507
nlimbs, highbits = divrem(nd, 8*sizeof(Limb))
507508
highbits > 0 && (nlimbs += 1)
508509
mask = highbits == 0 ? ~zero(Limb) : one(Limb)<<highbits - one(Limb)
509-
return RangeGeneratorBigInt(first(r), m, nlimbs, mask)
510+
nlimbsmax = max(nlimbs, abs(last(r).size), abs(first(r).size))
511+
return RangeGeneratorBigInt(first(r), m, nlimbs, nlimbsmax, mask)
510512
end
511513

512514

@@ -539,7 +541,7 @@ end
539541
function rand(rng::AbstractRNG, g::RangeGeneratorBigInt)
540542
x = BigInt()
541543
ccall((:__gmpz_realloc2, :libgmp), Void, (Ptr{BigInt}, Culong), &x,
542-
g.nlimbs*8*sizeof(Limb))
544+
g.nlimbsmax*8*sizeof(Limb))
543545
limbs = unsafe_wrap(Array, x.d, g.nlimbs)
544546
while true
545547
rand!(rng, limbs)

0 commit comments

Comments
 (0)