From a318ce67bed3482bae7ea13a92ab124c315fe7db Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 17 Jun 2011 20:15:33 +0200 Subject: [PATCH] Cache assembly lookup results - improves performance (especially for failed lookups) --- ILSpy/AssemblyList.cs | 4 ++++ ILSpy/LoadedAssembly.cs | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ILSpy/AssemblyList.cs b/ILSpy/AssemblyList.cs index 9585d71f0..d49ed3c23 100644 --- a/ILSpy/AssemblyList.cs +++ b/ILSpy/AssemblyList.cs @@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy /// Dirty flag, used to mark modifications so that the list is saved later bool dirty; + internal readonly ConcurrentDictionary assemblyLookupCache = new ConcurrentDictionary(); + /// /// The assemblies in this list. /// Needs locking for multi-threaded access! @@ -101,6 +103,7 @@ namespace ICSharpCode.ILSpy void Assemblies_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { + assemblyLookupCache.Clear(); // Whenever the assembly list is modified, mark it as dirty // and enqueue a task that saves it once the UI has finished modifying the assembly list. if (!dirty) { @@ -111,6 +114,7 @@ namespace ICSharpCode.ILSpy delegate { dirty = false; AssemblyListManager.SaveList(this); + assemblyLookupCache.Clear(); }) ); } diff --git a/ILSpy/LoadedAssembly.cs b/ILSpy/LoadedAssembly.cs index 147044157..fdfb2636b 100644 --- a/ILSpy/LoadedAssembly.cs +++ b/ILSpy/LoadedAssembly.cs @@ -17,11 +17,11 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Concurrent; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows.Threading; - using Mono.Cecil; namespace ICSharpCode.ILSpy @@ -133,6 +133,8 @@ namespace ICSharpCode.ILSpy if (!disposed) { disposed = true; assemblyLoadDisableCount--; + // clear the lookup cache since we might have stored the lookups failed due to DisableAssemblyLoad() + MainWindow.Instance.CurrentAssemblyList.assemblyLookupCache.Clear(); } } } @@ -177,6 +179,11 @@ namespace ICSharpCode.ILSpy } public LoadedAssembly LookupReferencedAssembly(string fullName) + { + return assemblyList.assemblyLookupCache.GetOrAdd(fullName, LookupReferencedAssemblyInternal); + } + + LoadedAssembly LookupReferencedAssemblyInternal(string fullName) { foreach (LoadedAssembly asm in assemblyList.GetAssemblies()) { if (asm.AssemblyDefinition != null && fullName.Equals(asm.AssemblyDefinition.FullName, StringComparison.OrdinalIgnoreCase))