Here’s a MWE of the allocating code (Julia 1.11.2):
function foo()
arr = [Ref(i) for i=1:100]
iter = (i for i in arr if rand()>0)
@time begin
elem, state = iterate(iter)
while true
next = iterate(iter, state)
isnothing(next) && break
elem, state = next
end
end
return nothing
end
foo()
which will show:
0.000003 seconds (200 allocations: 6.250 KiB)
If you make the element bitstype/immutable (Ref(i) → i) it becomes non-allocating, or if you remove the if rand()>0 it also becomes non-allocating. But the combination (which is unavoidable in my real code) apparently allocates every single element twice.
The allocations go away if you don’t use the global rng state:
using Random
function foo()
rng = Xoshiro(0)
arr = [Ref(i) for i=1:100]
iter = (i for i in arr if rand(rng)>0)
@time begin
elem, state = iterate(iter)
while true
next = iterate(iter, state)
isnothing(next) && break
elem, state = next
end
end
return nothing
end
new to Julia, what’s the use case of the Ref(i)? I get it’s an MWE though, but trying to figureout Rel
Also, the version without Ref(i), but using rand() doesn’t allocate for me:
julia> function foo()
arr = [i for i=1:100]
iter = (i for i in arr if rand()>0)
@time begin
elem, state = iterate(iter)
while true
next = iterate(iter, state)
isnothing(next) && break
elem, state = next
end
end
return nothing
end
foo (generic function with 1 method)
julia> foo()
0.000004 seconds
julia> versioninfo()
Julia Version 1.11.2
Commit 5e9a32e7af2 (2024-12-01 20:02 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 8 × Intel(R) Core(TM) i5-8400H CPU @ 2.50GHz
WORD_SIZE: 64
LLVM: libLLVM-16.0.6 (ORCJIT, skylake)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)