-
Notifications
You must be signed in to change notification settings - Fork 14k
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.