I was noticing that some packages implement their iterative algorithms using the Base.Iterators
methods by defining the algorithm iteration inside an iterate
function and then using that to iterate it. Others implement explicit for/while loops to iterate the algorithm.
That got me wondering, is there a benefit to using the Base.Iterators
approach over writing out explicit loops for the algorithm?
Implementing Base.iterate
is what enables the for
syntax. I’m not sure what you mean by explicit for/while loops, but I’m thinking you refer to when indexing is possible, like looping over an array using something like for i in 1:length(array)
.
One advantage of iterate
is that you don’t have to support indexing which often is more complicated than iteration. Sometimes it also just makes alot of sense from an API point of view.
Contrived example with an utterly pointless iterator which represents an infinite sequence of random numbers just to show an example when indexing is not needed:
julia> struct RandSeq
seed::Int
end
julia> import Random
julia> Base.iterate(itr::RandSeq, state=Random.MersenneTwister(itr.seed)) = return randn(state), state
julia> randseq = RandSeq(1)
RandSeq(1)
julia> for v in Iterators.Take(randseq, 5)
@show v
end
v = 0.2972879845354616
v = 0.3823959677906078
v = -0.5976344767282311
v = -0.01044524463737564
v = -0.839026854388764
julia> for v in Iterators.Take(randseq, 5)
@show v
end
v = 0.2972879845354616
v = 0.3823959677906078
v = -0.5976344767282311
v = -0.01044524463737564
v = -0.839026854388764
that’s really. are there performance penalties at all?