提交 e7f2534d 编写于 作者: P Paul Harrington

Merge pull request #812 from pharring/ConcurrentDictionaries

Reduce allocations from the ConcurrentDictionaries in TypeSymbol interface implementation maps.
......@@ -45,7 +45,23 @@ private class InterfaceInfo
// Key is implemented member (method, property, or event), value is implementing member (from the
// perspective of this type). Don't allocate until someone needs it.
internal ConcurrentDictionary<Symbol, SymbolAndDiagnostics> implementationForInterfaceMemberMap;
private ConcurrentDictionary<Symbol, SymbolAndDiagnostics> _implementationForInterfaceMemberMap;
public ConcurrentDictionary<Symbol, SymbolAndDiagnostics> ImplementationForInterfaceMemberMap
{
get
{
var map = _implementationForInterfaceMemberMap;
if (map != null)
{
return map;
}
// PERF: Avoid over-allocation. In many cases, there's only 1 entry and we don't expect concurrent updates.
map = new ConcurrentDictionary<Symbol, SymbolAndDiagnostics>(concurrencyLevel: 1, capacity: 1);
return Interlocked.CompareExchange(ref _implementationForInterfaceMemberMap, map, null) ?? map;
}
}
// key = interface method/property/event, value = explicitly implementing method/property/event declared on this type
internal Dictionary<Symbol, Symbol> explicitInterfaceImplementationMap;
......@@ -54,7 +70,7 @@ internal bool IsDefaultValue()
{
return allInterfaces.IsDefault &&
interfacesAndTheirBaseInterfaces == null &&
implementationForInterfaceMemberMap == null &&
_implementationForInterfaceMemberMap == null &&
explicitInterfaceImplementationMap == null;
}
}
......@@ -641,12 +657,17 @@ protected SymbolAndDiagnostics FindImplementationForInterfaceMemberWithDiagnosti
return SymbolAndDiagnostics.Empty;
}
if (info.implementationForInterfaceMemberMap == null)
// PERF: Avoid delegate allocation by splitting GetOrAdd into TryGetValue+TryAdd
var map = info.ImplementationForInterfaceMemberMap;
SymbolAndDiagnostics result;
if (map.TryGetValue(interfaceMember, out result))
{
Interlocked.CompareExchange(ref info.implementationForInterfaceMemberMap, new ConcurrentDictionary<Symbol, SymbolAndDiagnostics>(), null);
return result;
}
return info.implementationForInterfaceMemberMap.GetOrAdd(interfaceMember, this.ComputeImplementationAndDiagnosticsForInterfaceMember);
result = ComputeImplementationAndDiagnosticsForInterfaceMember(interfaceMember);
map.TryAdd(interfaceMember, result);
return result;
default:
return SymbolAndDiagnostics.Empty;
......
......@@ -139,7 +139,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Friend ReadOnly Property AllInterfacesNoUseSiteDiagnostics As ImmutableArray(Of NamedTypeSymbol)
Get
If (m_lazyAllInterfaces.IsDefault) Then
ImmutableInterlocked.InterlockedCompareExchange(m_lazyAllInterfaces, MakeAllInterfaces(), Nothing)
ImmutableInterlocked.InterlockedInitialize(m_lazyAllInterfaces, MakeAllInterfaces())
End If
Return m_lazyAllInterfaces
......@@ -478,13 +478,32 @@ Done:
Return Nothing
End If
If m_lazyImplementationForInterfaceMemberMap Is Nothing Then
Interlocked.CompareExchange(m_lazyImplementationForInterfaceMemberMap, New ConcurrentDictionary(Of Symbol, Symbol)(), Nothing)
' PERF: Avoid delegate allocation by splitting GetOrAdd into TryGetValue+TryAdd
Dim map = ImplementationForInterfaceMemberMap
Dim result As Symbol = Nothing
If map.TryGetValue(interfaceMember, result) Then
Return result
End If
Return m_lazyImplementationForInterfaceMemberMap.GetOrAdd(interfaceMember, AddressOf Me.ComputeImplementationForInterfaceMember)
result = ComputeImplementationForInterfaceMember(interfaceMember)
map.TryAdd(interfaceMember, result)
Return result
End Function
Private ReadOnly Property ImplementationForInterfaceMemberMap As ConcurrentDictionary(Of Symbol, Symbol)
Get
Dim map = m_lazyImplementationForInterfaceMemberMap
If map IsNot Nothing Then
Return map
End If
' PERF: Avoid over-allocation. In many cases, there's only 1 entry and we don't expect concurrent updates.
map = New ConcurrentDictionary(Of Symbol, Symbol)(concurrencyLevel:=1, capacity:=1)
Return If(Interlocked.CompareExchange(m_lazyImplementationForInterfaceMemberMap, map, Nothing), map)
End Get
End Property
''' <summary>
''' Compute the implementation for an interface member in this type, or Nothing if none.
''' </summary>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册