perf: Weaver ILPostProcessorAssemblyResolver uses ConcurrentDictionary to avoid multithreading locks

This commit is contained in:
mischa 2023-06-19 21:23:44 +08:00 committed by mischa
parent c5ad884145
commit c6be031783

View File

@ -14,7 +14,7 @@
// we need a custom resolver for ILPostProcessor.
#if UNITY_2020_3_OR_NEWER
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using System.Threading;
@ -26,8 +26,13 @@ namespace Mirror.Weaver
class ILPostProcessorAssemblyResolver : IAssemblyResolver
{
readonly string[] assemblyReferences;
readonly Dictionary<string, AssemblyDefinition> assemblyCache =
new Dictionary<string, AssemblyDefinition>();
// originally we used Dictionary + lock.
// Resolve() is called thousands of times for large projects.
// ILPostProcessor is multithreaded, so best to use ConcurrentDictionary without the lock here.
readonly ConcurrentDictionary<string, AssemblyDefinition> assemblyCache =
new ConcurrentDictionary<string, AssemblyDefinition>();
readonly ICompiledAssembly compiledAssembly;
AssemblyDefinition selfAssembly;
@ -55,8 +60,6 @@ public AssemblyDefinition Resolve(AssemblyNameReference name) =>
Resolve(name, new ReaderParameters(ReadingMode.Deferred));
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
{
lock (assemblyCache)
{
if (name.Name == compiledAssembly.Name)
return selfAssembly;
@ -88,10 +91,9 @@ public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters p
parameters.SymbolStream = MemoryStreamFor(pdb);
AssemblyDefinition assemblyDefinition = AssemblyDefinition.ReadAssembly(ms, parameters);
assemblyCache.Add(cacheKey, assemblyDefinition);
assemblyCache.TryAdd(cacheKey, assemblyDefinition);
return assemblyDefinition;
}
}
// find assemblyname in assembly's references
string FindFile(AssemblyNameReference name)