枚举Dictionary.Values vs Dictionary本身

时间:2016-04-16 00:53:05

标签: c# .net dictionary asp.net-core .net-core

我正在GitHub上探索ASP.NET核心的来源,看看ASP.NET团队用来加速框架的那种技巧。我看到一些引起我兴趣的东西。在ServiceProvider的源代码中,在Dispose实现中,它们枚举了一个字典,并且他们发表评论来表示性能技巧:

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

如果字典是这样列举的,有什么区别?

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

它会对性能产生影响吗?或者是因为分配ValueCollection会占用更多内存?

1 个答案:

答案 0 :(得分:10)

你是对的,这是关于内存消耗的。差异实际上在评论中有很好的描述:在堆上访问Value will allocate a ValueCollectionDictionary<TKey, TValue>属性,这是一个类(引用类型)。

foreach通过字典本身会调用GetEnumerator(),并返回Enumerator。这是struct,将在堆栈上而不是在堆上分配。