对Type.GetMethod()的重复调用在内部缓存

本文关键字:调用 在内部 缓存 Type GetMethod | 更新日期: 2023-09-27 17:52:59

在我的代码中,我有一些函数在CLR的一些各种静态函数上调用Type.GetMethod(string, Type[])。总共可能要查找30个左右不同的静态函数。但是由于父函数经常被调用,所以它们会被反复查找。我假设CLR会缓存MethodInfo结果,所以只有对每个唯一查找方法的第一次调用是昂贵的,但是我想要一些确认。

编辑:MethodInfo结果最终成为Expression树中Expression.Call()语句的参数。

实现我自己的缓存会更好/更可靠吗?如果我这样做,我可以缓存MethodInfo的结果一次在应用程序的开始,只是重新访问他们无限期?或者我应该像这样使用RuntimeMethodHandle:

// Obtaining a Handle from an MemberInfo
RuntimeMethodHandle handle = typeof(D).GetMethod("MyMethod").MethodHandle;
// Resolving the Handle back to the MemberInfo
MethodBase mb = MethodInfo.GetMethodFromHandle(handle);

这个片段来自:https://msdn.microsoft.com/en-us/magazine/cc163759.aspx#S8

我不清楚为什么我要缓存RuntimeMethodHandle而不仅仅是MethodInfo

对Type.GetMethod()的重复调用在内部缓存

我的问题与其说是快速调用,不如说是确保每次在相同的方法上调用Type.GetMethod()时不会产生大的命中

那么您需要为给定的方法名缓存MethodInfo对象。CLR不能保证它会为您缓存这些数据,而且实际上,调用GetMethod()的代价可能非常高,无论您多久调用一次,这取决于数据是否仍然被缓存。反射通常是昂贵的。如果可能的话,应该尽量避免,尤其是在考虑性能的时候。

在您的情况下,因为您正在处理Expression对象,这取决于您如何使用它们(没有一个好的,最小的完整的代码示例,不可能确切地知道在您的场景中什么是最好的),您可能会发现缓存编译表达式更有意义。更一般地说,显然,如果要缓存任何东西,最合理的做法是缓存处理过程中最远的结果,因为缓存键是不变的。

注意CLR dynamic类型对象缓存运行时成员解析。如果您不想自己弄乱缓存的实现,那么您可以将dynamic合并到表达式中,并让CLR处理动态命名方法的缓存。同样,如果没有更多具体场景的细节,就不可能确定这是否有效,更不用说在您的情况下这是否是一种有用的方法了。