在我的代码中,我有一些函数在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()时不会产生大的命中
那么您需要为给定的方法名缓存MethodInfo
对象。CLR不能保证它会为您缓存这些数据,而且实际上,调用GetMethod()
的代价可能非常高,无论您多久调用一次,这取决于数据是否仍然被缓存。反射通常是昂贵的。如果可能的话,应该尽量避免,尤其是在考虑性能的时候。
在您的情况下,因为您正在处理Expression
对象,这取决于您如何使用它们(没有一个好的,最小的, 完整的代码示例,不可能确切地知道在您的场景中什么是最好的),您可能会发现缓存编译表达式更有意义。更一般地说,显然,如果要缓存任何东西,最合理的做法是缓存处理过程中最远的结果,因为缓存键是不变的。
注意CLR 为dynamic
类型对象缓存运行时成员解析。如果您不想自己弄乱缓存的实现,那么您可以将dynamic
合并到表达式中,并让CLR处理动态命名方法的缓存。同样,如果没有更多具体场景的细节,就不可能确定这是否有效,更不用说在您的情况下这是否是一种有用的方法了。