-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
What it does
This suggests replacing iter.count() > 0
(or >= 1
or != 0
) with iter.next().is_some()
and iter.count() == 0
(or < 1
) with iter.next().is_none()
.
This could go in perf.
Advantage
This avoids potentially having to run through the whole iterator, if the optimiser can't see through it. In at least one case, it can't.
Along with filter_next and search_is_some, this completes a path that can transform one of the obvious naïve ways to write Iterator::any
into the genuine article.
xs.filter(|&x| x == 3).count() > 0
→
xs.filter(|&x| x == 3).next().is_some()
→ (filter_next)
xs.find(|&x| x == 3).is_some()
→ (search_is_some)
xs.any(|x| x == 3)
The overall benefit here looks significant.
Drawbacks
If running through the iterator has side effects, then the behaviour will change.
The resulting code is five characters longer, and requires the underlying variable to be mutable.
Example
fn empty<T>(xs: impl Iterator<Item = T>) -> bool {
xs.count() == 0
}
Could be written as:
fn empty<T>(mut xs: impl Iterator<Item = T>) -> bool {
xs.next().is_none()
}
Comparison with existing lints
No response
Additional Context
No response