Skip to content

Prevent garbage collection when iterating empty Simple Injector collections #1020

@dotnetjunkie

Description

@dotnetjunkie

Consider the following class:

public sealed class LoggerComposite(IEnumerable<ILogger> loggers) : ILogger
{
    public void Log(LogEntry entry)
    {
        foreach (var logger in loggers) logger.Log(entry);
    }
}

In Simple Injector v5.5, iterating the collection loggers always causes a new enumerator to be created, thus causing garbage collection, even when the collection of loggers is empty.

Because the injected collection is (in most cases) a Simple Injector-defined type (i.e. the internal ContainerControlledCollection<T>), it allows returning a single default enumerator.

This optimization is especially useful in scenarios the majority of cases contains no elements to iterate. This becomes more obvious when the iterated element itself is generic, for instance:

public sealed class CompositeBusinessRule<TEntity>(IEnumerable<IBusinessRule<TEntity>> rules)
    : IBusinessRule<TEntity>
{
    public void Validate(TEntity entity)
    {
        foreach (var rule in rules) rule.Validate();
    }
}

If most of the rules in the system contain no implementations, the Validate method is able to run without causing garbage collection on them.

Unfortunately, garbage collection can't be prevented in case a collection contains elements.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions