From 2ae542f17d9cbbadd9dce8d5828a0e0e10ef3b36 Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Fri, 31 May 2019 18:09:16 +0200 Subject: [PATCH 1/2] faster rand(::Tuple) for power of two lengths --- stdlib/Random/src/generation.jl | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/stdlib/Random/src/generation.jl b/stdlib/Random/src/generation.jl index f85447715794b..caa5e3cde3f45 100644 --- a/stdlib/Random/src/generation.jl +++ b/stdlib/Random/src/generation.jl @@ -464,20 +464,25 @@ function rand(rng::AbstractRNG, sp::SamplerSimple{Tuple{A,B,C}}) where {A,B,C} @inbounds return sp[][1 + r รท 0x0005555555555555] end -### 4 - -Sampler(RNG::Type{<:AbstractRNG}, t::Tuple{A,B,C,D}, n::Repetition) where {A,B,C,D} = - SamplerSimple(t, Sampler(RNG, UInt52Raw(Int), n)) - -function rand(rng::AbstractRNG, sp::SamplerSimple{Tuple{A,B,C,D}}) where {A,B,C,D} - r = rand(rng, sp.data) & 3 - @inbounds return sp[][1 + r] -end - ### n -Sampler(RNG::Type{<:AbstractRNG}, t::Tuple, n::Repetition) = - SamplerSimple(t, Sampler(RNG, Base.OneTo(length(t)), n)) +@generated function Sampler(RNG::Type{<:AbstractRNG}, t::Tuple, n::Repetition) + l = fieldcount(t) + if l < typemax(UInt32) && ispow2(l) + :(SamplerSimple(t, Sampler(RNG, UInt32, n))) + else + :(SamplerSimple(t, Sampler(RNG, Base.OneTo(length(t)), n))) + end +end -rand(rng::AbstractRNG, sp::SamplerSimple{<:Tuple}) = - @inbounds return sp[][rand(rng, sp.data)] +@generated function rand(rng::AbstractRNG, sp::SamplerSimple{T}) where T<:Tuple + l = fieldcount(T) + if l < typemax(UInt32) && ispow2(l) + quote + r = rand(rng, sp.data) & ($l-1) + @inbounds return sp[][1 + r] + end + else + :(@inbounds return sp[][rand(rng, sp.data)]) + end +end From 59b56ce1beff537b82aca6db4b2a5e6ccea6713a Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Fri, 31 May 2019 18:10:27 +0200 Subject: [PATCH 2/2] faster rand(::MersenneTwister, ::OneTo) This was an oversight. This makes rand(::MersenneTwister, ::Tuple) generally faster. --- stdlib/Random/src/RNGs.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/Random/src/RNGs.jl b/stdlib/Random/src/RNGs.jl index 0b929e1ebbf12..899147313fb2b 100644 --- a/stdlib/Random/src/RNGs.jl +++ b/stdlib/Random/src/RNGs.jl @@ -601,7 +601,7 @@ end #### from a range for T in BitInteger_types, R=(1, Inf) # eval because of ambiguity otherwise - @eval Sampler(::Type{MersenneTwister}, r::UnitRange{$T}, ::Val{$R}) = + @eval Sampler(::Type{MersenneTwister}, r::AbstractUnitRange{$T}, ::Val{$R}) = SamplerRangeFast(r) end