提交 35e9635b 编写于 作者: S Sam Harwell

Optimize OrderPreservingMultiDictionary<TKey, TValue>.TryGetValue

The indexer for OrderPreservingMultiDictionary<K, V> creates a new array
for each usage. This change implements a TryGetValue for the collection
with a predicate to avoid the need to use the indexer on a
SymbolTreeInfo hot path.
上级 fc6da2df
......@@ -9,6 +9,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.CodeAnalysis.Collections
......@@ -109,6 +110,18 @@ public void Add(K k, V v)
}
}
public bool TryGetValue<TArg>(K key, Func<V, TArg, bool> predicate, TArg arg, [MaybeNullWhen(false)] out V value)
{
if (_dictionary is not null && _dictionary.TryGetValue(key, out var valueSet))
{
Debug.Assert(valueSet.Count >= 1);
return valueSet.TryGetValue(predicate, arg, out value);
}
value = default;
return false;
}
public Dictionary<K, ValueSet>.Enumerator GetEnumerator()
{
return _dictionary is null ? s_emptyDictionary.GetEnumerator() : _dictionary.GetEnumerator();
......@@ -206,6 +219,35 @@ internal void Free()
}
}
public bool TryGetValue<TArg>(Func<V, TArg, bool> predicate, TArg arg, [MaybeNullWhen(false)] out V value)
{
Debug.Assert(this.Count >= 1);
var arrayBuilder = _value as ArrayBuilder<V>;
if (arrayBuilder is not null)
{
foreach (var v in arrayBuilder)
{
if (predicate(v, arg))
{
value = v;
return true;
}
}
}
else
{
var singleValue = (V)_value;
if (predicate(singleValue, arg))
{
value = singleValue;
return true;
}
}
value = default;
return false;
}
internal bool Contains(V item)
{
Debug.Assert(this.Count >= 1);
......
......@@ -683,14 +683,11 @@ private void EnsureParentsAndChildren(List<string> simpleNames)
private MetadataNode GetOrCreateChildNode(
MetadataNode currentNode, string simpleName)
{
foreach (var childNode in _parentToChildren[currentNode])
if (_parentToChildren.TryGetValue(currentNode, static (childNode, simpleName) => childNode.Name == simpleName, simpleName, out var childNode))
{
if (childNode.Name == simpleName)
{
// Found an existing child node. Just return that and all
// future parts off of it.
return childNode;
}
// Found an existing child node. Just return that and all
// future parts off of it.
return childNode;
}
// Couldn't find a child node with this name. Make a new node for
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册