Skip to content

Commit

Permalink
Improve cache performance of MethodFinder.GetAllInstanceMethods
Browse files Browse the repository at this point in the history
  • Loading branch information
tangdf authored and jonorossi committed Jun 1, 2018
1 parent fd0a0e8 commit 9ada611
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 22 deletions.
31 changes: 10 additions & 21 deletions src/Castle.Core/DynamicProxy/Generators/MethodFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Castle.DynamicProxy.Generators
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

/// <summary>
Expand All @@ -24,7 +25,7 @@ namespace Castle.DynamicProxy.Generators
/// </summary>
public class MethodFinder
{
private static readonly Dictionary<Type, object> cachedMethodInfosByType = new Dictionary<Type, object>();
private static readonly Dictionary<Type, MethodInfo[]> cachedMethodInfosByType = new Dictionary<Type, MethodInfo[]>();
private static readonly object lockObject = new object();

public static MethodInfo[] GetAllInstanceMethods(Type type, BindingFlags flags)
Expand All @@ -38,16 +39,18 @@ public static MethodInfo[] GetAllInstanceMethods(Type type, BindingFlags flags)

lock (lockObject)
{
if (!cachedMethodInfosByType.ContainsKey(type))
if (!cachedMethodInfosByType.TryGetValue(type, out methodsInCache))
{
// We always load all instance methods into the cache, we will filter them later
methodsInCache = type.GetMethods(
BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance)
.Distinct(MethodSignatureComparer.Instance)
.ToArray();
cachedMethodInfosByType.Add(
type,
RemoveDuplicates(type.GetMethods(
BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance)));
methodsInCache);
}
methodsInCache = (MethodInfo[])cachedMethodInfosByType[type];
}
return MakeFilteredCopy(methodsInCache, flags & (BindingFlags.Public | BindingFlags.NonPublic));
}
Expand Down Expand Up @@ -76,19 +79,5 @@ private static MethodInfo[] MakeFilteredCopy(MethodInfo[] methodsInCache, Bindin
return result.ToArray();
}

private static object RemoveDuplicates(MethodInfo[] infos)
{
var uniqueInfos = new Dictionary<MethodInfo, object>(MethodSignatureComparer.Instance);
foreach (var info in infos)
{
if (!uniqueInfos.ContainsKey(info))
{
uniqueInfos.Add(info, null);
}
}
var result = new MethodInfo[uniqueInfos.Count];
uniqueInfos.Keys.CopyTo(result, 0);
return result;
}
}
}
}
2 changes: 1 addition & 1 deletion src/Castle.Core/DynamicProxy/Internal/InvocationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,4 @@ public override int GetHashCode()
}
}
}
}
}

0 comments on commit 9ada611

Please sign in to comment.