提交 8c6690c1 编写于 作者: S Sam Harwell 提交者: GitHub

Merge pull request #20479 from sharwell/rm-boxing-alloc

Eliminate a boxing allocation in DiagnosticIncrementalAnalyzer.InMemoryStorage
......@@ -12,10 +12,10 @@ internal partial class DiagnosticIncrementalAnalyzer
private static class InMemoryStorage
{
// the reason using nested map rather than having tuple as key is so that I dont have a gigantic map
private readonly static ConcurrentDictionary<DiagnosticAnalyzer, ConcurrentDictionary<object, CacheEntry>> s_map =
new ConcurrentDictionary<DiagnosticAnalyzer, ConcurrentDictionary<object, CacheEntry>>(concurrencyLevel: 2, capacity: 10);
private readonly static ConcurrentDictionary<DiagnosticAnalyzer, ConcurrentDictionary<(object key, string stateKey), CacheEntry>> s_map =
new ConcurrentDictionary<DiagnosticAnalyzer, ConcurrentDictionary<(object key, string stateKey), CacheEntry>>(concurrencyLevel: 2, capacity: 10);
public static bool TryGetValue(DiagnosticAnalyzer analyzer, object key, out CacheEntry entry)
public static bool TryGetValue(DiagnosticAnalyzer analyzer, (object key, string stateKey) key, out CacheEntry entry)
{
AssertKey(key);
......@@ -29,16 +29,16 @@ public static bool TryGetValue(DiagnosticAnalyzer analyzer, object key, out Cach
return true;
}
public static void Cache(DiagnosticAnalyzer analyzer, object key, CacheEntry entry)
public static void Cache(DiagnosticAnalyzer analyzer, (object key, string stateKey) key, CacheEntry entry)
{
AssertKey(key);
// add new cache entry
var analyzerMap = s_map.GetOrAdd(analyzer, _ => new ConcurrentDictionary<object, CacheEntry>(concurrencyLevel: 2, capacity: 10));
var analyzerMap = s_map.GetOrAdd(analyzer, _ => new ConcurrentDictionary<(object key, string stateKey), CacheEntry>(concurrencyLevel: 2, capacity: 10));
analyzerMap[key] = entry;
}
public static void Remove(DiagnosticAnalyzer analyzer, object key)
public static void Remove(DiagnosticAnalyzer analyzer, (object key, string stateKey) key)
{
AssertKey(key);
// remove the entry
......@@ -62,10 +62,9 @@ public static void DropCache(DiagnosticAnalyzer analyzer)
}
// make sure key is either documentId or projectId
private static void AssertKey(object key)
private static void AssertKey((object key, string stateKey) key)
{
var tuple = (ValueTuple<object, string>)key;
Contract.ThrowIfFalse(tuple.Item1 is DocumentId || tuple.Item1 is ProjectId);
Contract.ThrowIfFalse(key.key is DocumentId || key.key is ProjectId);
}
}
......
......@@ -412,7 +412,7 @@ private Task<StrongBox<ImmutableArray<DiagnosticData>>> DeserializeAsync(Diagnos
// after initial deserialization, we track actual document/project that actually have diagnostics so no data won't be a common
// case.
// check cache first
if (InMemoryStorage.TryGetValue(_owner.Analyzer, ValueTuple.Create(key, stateKey), out var entry) && serializer.Version == entry.Version)
if (InMemoryStorage.TryGetValue(_owner.Analyzer, (key, stateKey), out var entry) && serializer.Version == entry.Version)
{
if (entry.Diagnostics.Length == 0)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册