Are all clones evil?

43 points yoav-lavi

Hi!

I'm learning Rust and working on a project that consumes iterators in many places to parse a tree like structure that has positional components (Pest output).

I've found myself cloning iterators in multiple places when I want to extract positional arguments from an iterator (e.g. first, last, and nth) and can't be sure how many elements will be present. In these cases treating the iterator as if it were an immutable vector is convenient, as for instance calling next and last on the same iterator will not consume it for further operations.

I understand that cloning often is frowned upon^(\[1\]) (although I've also seen conflicting advice^(\[2\])), but since cloning an iterator does not clone the underlying contents^(\[3\]), is this normally seen as an issue? It would be possible to avoid cloning or "memory-golf" in these cases by checking the size and adjusting the consuming operations to specific cases, but that may result in less readable code in this case.

I've also tried collecting the iterator before checking the positional locations but that results in worse performance.

I'm aware that one should benchmark before deciding whether something is the correct solution, but I wanted to also hear opinions and best practices around the matter.

Thank you!


^(\[1\]) Tim McNamara - Rust in Action - 4.5.3 - Duplicate the value:

One alternative to refactoring is to simply copy values. Doing this often is typically frowned upon, ...

^(\[2\]) https://twitter.com/ekuber/status/1476128384908410882

clone liberally

^(\[3\]) https://stackoverflow.com/a/45195881