2016-04-16 16 views
10

Stavo esplorando le fonti del core ASP.NET su GitHub per vedere che tipo di trucchi il team di ASP.NET usava per velocizzare il framework. Ho visto qualcosa che mi ha incuriosito. Nel codice sorgente del ServiceProvider, nell'attuazione Dispose, si enumerano un dizionario, e hanno messo un commento per indicare un trucco prestazioni:Enumerate Dictionary.Values ​​vs Dizionario stesso

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();   
} 

Qual è la differenza se il dizionario è enumerato in quel modo?

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

Ha un impatto sulle prestazioni? Oppure perché allocare uno ValueCollection consumerà più memoria?

risposta

8

Hai ragione, si tratta di consumo di memoria. La differenza è in realtà abbastanza ben descritta nel commento: accesso alla proprietà Value di un Dictionary<TKey, TValue>will allocate a ValueCollection, che è una classe (tipo di riferimento), nell'heap.

foreach 'attraverso il dizionario stesso provoca una chiamata a GetEnumerator() che restituisce un Enumerator. Questo è un struct e verrà assegnato nello stack anziché nell'heap.

+1

Sembra che mi sia mancato il concetto di accumulo e impilamento che è ben descritto qui http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx Grazie a proposito. –