Skip to content

Commit 3c1d672

Browse files
committed
faster rand!(::UnitRange{BigInt})
The cumulated improvement in performance together with the previous commit is of the order of 50%.
1 parent 8a751b2 commit 3c1d672

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

base/random/RNGs.jl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ end
302302
Base.length(a::UnsafeView) = a.len
303303
Base.getindex(a::UnsafeView, i::Int) = unsafe_load(a.ptr, i)
304304
Base.setindex!(a::UnsafeView, x, i::Int) = unsafe_store!(a.ptr, x, i)
305+
Base.pointer(a::UnsafeView) = a.ptr
306+
Base.size(a::UnsafeView) = (a.len,)
305307

306308
# this is essentially equivalent to rand!(r, ::AbstractArray{Float64}, I) above, but due to
307309
# optimizations which can't be done currently when working with pointers, we have to re-order
@@ -424,7 +426,7 @@ end
424426

425427
#### arrays of integers
426428

427-
function _rand!(r::MersenneTwister, A::UnsafeView{UInt128})
429+
function rand!(r::MersenneTwister, A::UnsafeView{UInt128}, ::SamplerType{UInt128})
428430
n::Int=length(A)
429431
i = n
430432
while true
@@ -450,10 +452,15 @@ function _rand!(r::MersenneTwister, A::UnsafeView{UInt128})
450452
end
451453

452454
for T in BitInteger_types
453-
@eval function rand!(r::MersenneTwister, A::Array{$T}, ::SamplerType{$T})
455+
@eval rand!(r::MersenneTwister, A::Array{$T}, sp::SamplerType{$T}) =
456+
(@gc_preserve A rand!(r, UnsafeView(pointer(A), length(A)), sp); A)
457+
458+
T == UInt128 && continue
459+
460+
@eval function rand!(r::MersenneTwister, A::UnsafeView{$T}, ::SamplerType{$T})
454461
n = length(A)
455462
n128 = n * sizeof($T) ÷ 16
456-
@gc_preserve A _rand!(r, UnsafeView{UInt128}(pointer(A), n128))
463+
rand!(r, UnsafeView{UInt128}(pointer(A), n128))
457464
for i = 16*n128÷sizeof($T)+1:n
458465
@inbounds A[i] = rand(r, $T)
459466
end

base/random/generation.jl

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -278,17 +278,19 @@ end
278278

279279
function rand(rng::AbstractRNG, sp::SamplerBigInt)
280280
x = MPZ.realloc2(sp.nlimbsmax*8*sizeof(Limb))
281-
limbs = unsafe_wrap(Array, x.d, sp.nlimbs)
282-
while true
283-
rand!(rng, limbs)
284-
@inbounds limbs[end] &= sp.mask
285-
MPZ.mpn_cmp(x, sp.m, sp.nlimbs) <= 0 && break
286-
end
287-
# adjust x.size (normally done by mpz_limbs_finish, in GMP version >= 6)
288-
x.size = sp.nlimbs
289-
while x.size > 0
290-
@inbounds limbs[x.size] != 0 && break
291-
x.size -= 1
281+
@gc_preserve x begin
282+
limbs = UnsafeView(x.d, sp.nlimbs)
283+
while true
284+
rand!(rng, limbs)
285+
limbs[end] &= sp.mask
286+
MPZ.mpn_cmp(x, sp.m, sp.nlimbs) <= 0 && break
287+
end
288+
# adjust x.size (normally done by mpz_limbs_finish, in GMP version >= 6)
289+
x.size = sp.nlimbs
290+
while x.size > 0
291+
limbs[x.size] != 0 && break
292+
x.size -= 1
293+
end
292294
end
293295
MPZ.add!(x, sp.a)
294296
end

0 commit comments

Comments
 (0)