Iterators
collect
and extend
Iterator::collect
converts an iterator into a collection such as Vec
,
which typically requires an allocation. You should avoid calling collect
if
the collection is then only iterated over again.
For this reason, it is often better to return an iterator type like impl Iterator<Item=T>
from a function than a Vec<T>
. Note that sometimes
additional lifetimes are required on these return types, as this blog post
explains.
Example.
Similarly, you can use extend
to extend an existing collection (such as a
Vec
) with an iterator, rather than collecting the iterator into a Vec
and
then using append
.
Finally, when you write an iterator it is often worth implementing the
Iterator::size_hint
or ExactSizeIterator::len
method, if possible.
collect
and extend
calls that use the iterator may then do fewer
allocations, because they have advance information about the number of elements
yielded by the iterator.
Chaining
chain
can be very convenient, but it can also be slower than a single
iterator. It may be worth avoiding for hot iterators, if possible.
Example.
Similarly, filter_map
may be faster than using filter
followed by
map
.
Chunks
When a chunking iterator is required and the chunk size is known to exactly
divide the slice length, use the faster slice::chunks_exact
instead of slice::chunks
.
When the chunk size is not known to exactly divide the slice length, it can
still be faster to use slice::chunks_exact
in combination with either
ChunksExact::remainder
or manual handling of excess elements.
Example 1,
Example 2.
The same is true for related iterators: