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 committed Jul 10, 2023
1 parent 02b798a commit d6997f7
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/Moq/Extensions.cs
Original file line number Diff line number Diff line change
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 @@ -134,7 +135,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 All @@ -151,6 +152,13 @@ public static MethodInfo GetImplementingMethod(this MethodInfo method, Type prox
}
}

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));
}

public static object InvokePreserveStack(this Delegate del, IReadOnlyList<object> args = null)
{
try
Expand Down

0 comments on commit d6997f7

Please sign in to comment.