From eb8ccf96536cae551d359a28e143a1cf46e4ac77 Mon Sep 17 00:00:00 2001 From: Andre Date: Sun, 6 Aug 2023 16:42:47 +0200 Subject: [PATCH] Improve performance for mocking interfaces: Cache GetInterfaceMap Fixes #1350. --- src/Moq/Extensions.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Moq/Extensions.cs b/src/Moq/Extensions.cs index d975aea48..4a09e6309 100644 --- a/src/Moq/Extensions.cs +++ b/src/Moq/Extensions.cs @@ -2,6 +2,7 @@ // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -155,7 +156,7 @@ public static MethodInfo GetImplementingMethod(this MethodInfo method, Type prox { Debug.Assert(declaringType.IsAssignableFrom(proxyType)); - var map = proxyType.GetInterfaceMap(method.DeclaringType); + var map = GetInterfaceMap(proxyType, method.DeclaringType); var index = Array.IndexOf(map.InterfaceMethods, method); Debug.Assert(index >= 0); return map.TargetMethods[index].GetBaseDefinition(); @@ -518,6 +519,13 @@ public static Type SubstituteTypeMatchers(this Type type, Type other) return type; } + private static readonly ConcurrentDictionary, InterfaceMapping> mappingsCache = new (); + + private static InterfaceMapping GetInterfaceMap(Type type, Type interfaceType) + { + return mappingsCache.GetOrAdd(Tuple.Create(type, interfaceType), tuple => tuple.Item1.GetInterfaceMap(tuple.Item2)); + } + public static IEnumerable FindAllInnerMocks(this SetupCollection setups) { return setups.FindAll(setup => !setup.IsConditional)