Implementation of iterators by the compiler really uses class objects, and using (with foreach, for example) an iterator implemented with yield return will actually cause memory allocation. In the scheme of things, this is rarely a problem, because either significant work is performed when the iteration is performed, or a much larger amount of memory is allocated during the iteration by other things.
For the memory allocated by the iterator to become a problem, your application must be intensive, and your algorithms must work with objects without allocating any memory. Think of the Games of Life of something like this. Suddenly, the iteration itself overflows. And when the iteration allocates memory, a huge amount of memory can be allocated.
If your application matches this profile (and only if), then the first rule you should follow:
- Avoid iterators in inner loops when a simpler iterative concept is available.
For example, if you have an array or list, such as a data structure, you already expand the indexer property and the count property so that clients can simply use the for loop instead of using foreach with your iterator. This is “easy money” for shortening GC, and it does not make your code ugly or bloated, a little less elegant.
The second principle that you must follow is:
- measure memory allocations to see when and where you should use the first rule.
source share