Skip to content

Commit

Permalink
Improve performance for mocking interfaces: Cache GetInterfaceMap
Browse files Browse the repository at this point in the history
Fixes #1350.
  • Loading branch information
rauhs authored and Andre committed Aug 6, 2023
1 parent 6057dd2 commit 7cca704
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/Moq/Extensions.cs
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -427,6 +428,13 @@ static MethodInfo GetInvokeMethodFromUntypedDelegateCallback(Delegate callback)
return null;
}
}

private static readonly ConcurrentDictionary<Tuple<Type, Type>, InterfaceMapping> mappingsCache = new ();

private static InterfaceMapping GetInterfaceMap(Type type, Type interfaceType)
{
return mappingsCache.GetOrAdd(Tuple.Create(type, interfaceType), tuple => tuple.Item1.GetInterfaceMap(tuple.Item2));
}

/// <summary>
/// Visits all constituent parts of <paramref name="type"/>, replacing all type matchers
Expand Down

0 comments on commit 7cca704

Please sign in to comment.