Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumerate Dictionary.Values vs Dictionary itself

I was exploring the sources of ASP.NET core on GitHub to see what kind of tricks the ASP.NET team used to speed up the framework. I saw something that intrigued me. In the source code of the ServiceProvider, in the Dispose implementation, they enumerate a dictionary, and they put a comment to indicate a performance trick :

private readonly Dictionary<IService, object> _resolvedServices = new Dictionary<IService, object>();

// Code removed for brevity

public void Dispose()    
{        
    // Code removed for brevity

    // PERF: We've enumerating the dictionary so that we don't allocate to enumerate.
    // .Values allocates a KeyCollection on the heap, enumerating the dictionary allocates
    // a struct enumerator
    foreach (var entry in _resolvedServices)
    {
        (entry.Value as IDisposable)?.Dispose();
    }

    _resolvedServices.Clear();        
}

What is the difference if the dictionary is enumerated like that ?

foreach (var entry in _resolvedServices.Values)
{
    (entry as IDisposable)?.Dispose();
}

It has a performance impact ? Or it's because allocate a ValueCollection will consume more memory ?

like image 908
Fabien ESCOFFIER Avatar asked Apr 16 '16 00:04

Fabien ESCOFFIER


People also ask

Can I use enumerate with dictionary?

The enumerate() function in Python returns an enumerate-type object and adds a counter variable to iterate over a list or some other type of collection. It makes looping over such objects easier. We can also use the enumerate() function with dictionaries as well.

Does enumerate create a dictionary?

By using enumerate() , we can convert a list into a dictionary with index as key and list item as the value.


1 Answers

You're right, this is about memory consumption. The difference is actually pretty well described in the comment: accessing the Value property of a Dictionary<TKey, TValue> will allocate a ValueCollection, which is a class (reference type), on the heap.

foreach'ing through the dictionary itself results in a call to GetEnumerator() which returns an Enumerator. This is a struct and will be allocated on the stack rather than on the heap.

like image 94
Henk Mollema Avatar answered Oct 17 '22 14:10

Henk Mollema