Performance of the iterator approach

I started using IterativeSolvers.jl in some of my work and found the iterator-based code to be easy on the eyes and rather slick. It seems to me that any Julia implementation of an iterative algorithm ought to adopt this style.

However, my reading of the various forum posts here suggests there is quite a bit of subtlety involved in the performance of iterators especially as they compare to a loop-based style. My takeaway from the discussion here:

  1. It should be possible to make an iterator as fast as a loop, and
  2. you can make an iterator (slightly) faster if you really know what you’re doing.

Syntactic sugar aside, I’m wondering if there are any general guidelines in choosing an iterator vs a loop approach? Are there patterns that should be avoided or that preclude a fast iterator implementation? Perhaps I’m asking the wrong question.

Separate but related question: Is there a goal to implement iterators for every algorithm currently in IterativeSolvers.jl? I could not find anything in the issues page or documentation.

If you are solving linear algebra problems using an iterative approach, I would assume that the calculation itself would dominate any possible difference in how you call it in the outer loop.

There is also some confusion implicit in the question: a loop like

for i in 1:n
    ...
end

also uses an iterator. Or were you thinking about a while loop?

Generally the compiler can compile efficient code for iterators just fine. If you are allocating for the result, make sure that the relevant traits are there to provide all the information that is otherwise available, but even without that it can be pretty efficient using the heuristics of collect.

1 Like

Thank you for your response.

Yes, I did not realize that UnitRange and StepRange are also iterators.

Just to check I understand your last point: calling collect(iter) for a custom iterator that supports the HasLength() trait can allocate the required space before walking through each value. Otherwise, the container storing the result is may be resized during iteration.

Yes. But even when the length is not known before, the resizing algorithm is clever about overallocating so it may not be a big overhead for large vectors. When speed is imporant, profile to see if it is a bottleneck and then benchmark.

Then again, for a linear algebra problem where iterative methods are required this will be the least of your problems.

1 Like