KEMBAR78
Eliminate allocations when enumerating empty collections · Issue #59596 · dotnet/runtime · GitHub
Skip to content

Eliminate allocations when enumerating empty collections #59596

@geeknoid

Description

@geeknoid

Turns out the world is full of empty collections. Empty lists, empty dictionaries, empty sets. The world is also full of code that ends up enumerating these empty collections. And if this code happens to hold an interface type such as IList<T> or IReadOnlyList<T>, then enumerating these empty collections causes a heap allocation:

IReadOnlyList<int> l = new List<int>();
foreach (var foo in l)   // <-- allocates an enumerator, *sigh*
{
}

It should be possible to eliminate these allocations by adding a teeny bit of logic to the collection types. For example, consider List<T>:

public class List<T>
{
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
        => (_size == 0) ? _staticEmptyEnumerator : new Enumerator(this);

    private static readonly EmptyEnumerator _staticEmptyEnumerator = new ();

    private sealed class EmptyEnumerator : IEnumerator<T>
    {
        public void Dispose() {}
        public bool MoveNext() => false;
        public void Reset() {}
        public T Current => throw new NotSupportedException();
        object IEnumerator.Current => throw new NotSupportedException();
    }
}

The above code detects if the collection is empty and then returns a static enumerator instance to the caller. No allocation occurs, the world is a slightly better place as a result.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions