Skip to content

Commit d2dded3

Browse files
committed
rely on shuffle! and on escape analysis instead of on recursion
1 parent cf637f0 commit d2dded3

File tree

1 file changed

+11
-18
lines changed

1 file changed

+11
-18
lines changed

stdlib/Random/src/misc.jl

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -183,26 +183,19 @@ ltm52(n::Int, mask::Int=nextpow(2, n)-1) = LessThan(n-1, Masked(mask, UInt52Raw(
183183

184184
## shuffle & shuffle!
185185

186-
function _tuple_without_element_at_index(tup::(Tuple{T, Vararg{T, N}} where {T}), i::Int) where {N}
187-
clo = let tup = tup, i = i
188-
function closure(j::Int)
189-
k = if j < i
190-
j
191-
else
192-
j + 1
193-
end
194-
tup[k]
195-
end
196-
end
197-
ntuple(clo, Val{N}())
198-
end
199-
200186
function shuffle(rng::AbstractRNG, tup::(Tuple{Vararg{T, N}} where {T})) where {N}
201187
if tup isa Tuple{Any, Vararg}
202-
let i = rand(rng, Base.OneTo(N)) # Fisher–Yates shuffle
203-
s = _tuple_without_element_at_index(tup, i)
204-
t = shuffle(rng, s)
205-
(tup[i], t...)
188+
@inline let # `@inline` and `@inbounds` are here to help escape analysis
189+
clo = @inbounds let mem = Memory{UInt16}(undef, N) # use `UInt16` to save stack space/prevent heap allocation
190+
copyto!(mem, Base.OneTo(N))
191+
shuffle!(mem)
192+
let mem = mem, tup = tup
193+
function closure(i::Int)
194+
@inbounds tup[mem[i]]
195+
end
196+
end
197+
end
198+
ntuple(clo, Val{N}())
206199
end
207200
else
208201
tup

0 commit comments

Comments
 (0)