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: