Description
step_by
has to special case the first element and this behaviour can act as a performance block because of the necessary branch in next
as seen with integer ranges. This branch can be removed, by always taking the next element and also stepping ahead in one go but that changes the semantics when the iterator has side-effects.
step_by
will be stabilized with the next release and I fear that the need to preserve semantics may lock us into a sub-optimally performing step_by
or some other lacking solution. I propose that we amend a note to step_by
, allowing us to use the "always take and step ahead" semantics for optimization for now. In the future, when we have this issue figured out, we can then limit the cases where pre-stepping is allowed. The general case should not use it.
One example where preserving semantics causes inefficiency is RangeFrom
iterators. When pre-stepping, a RangeFrom
will overflow its start
member one iteration earlier and will therefore, in debug mode, panic one iteration earlier. That may cause a panic in a program that doesn't actually use any elements after the overflow, i.e. a program without any user error. If we have to preserve these semantics, RangeFrom
can not be optimized for step_by
.
(RangeFrom
reserves the right to change overflow behaviour so we could "fix" this particular one by allowing overflow in debug mode)
Furthermore, if range iterators need to pre-step for performance reasons, then the currently still unstable Step
trait's step*
methods must be limited to be side-effect free or the pre-stepping optimization would be invalid.