在我的代码中,我有一些函数在CLR的各种静态函数上调用Type.GetMethod(string, Type[])
。总共可以查找30个左右的不同静态函数。但是他们经常被反复查找,因为父函数经常被调用。我假设CLR会缓存MethodInfo
结果,所以只有第一次调用每个独特的查找方法成本很高,但我想要一些确认。
编辑:MethodInfo
结果最终成为Expression.Call()
树中Expression
语句的参数。
实现自己的缓存会更好/更可靠吗?如果我这样做,我可以在应用程序的最开始一次缓存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
。
答案 0 :(得分:2)
我的问题不是一个快速的调用,因为它确保Type.GetMethod()调用不会在每次使用相同的方法调用时产生大的命中
然后,您需要为给定的方法名称缓存MethodInfo
对象。 CLR并不保证它会为您缓存这一点,实际上,无论您多久使用一次,调用GetMethod()
都会非常昂贵,具体取决于数据是否仍然被缓存。反射总的来说很昂贵。如果可能的话,应该避免这种情况,尤其是在考虑性能时。
在您的情况下,由于您正在处理Expression
个对象,具体取决于您使用它们的确切程度(没有a good, minimal, complete code example,因此无法确定您的方案中哪个最佳),可能会发现缓存已编译的表达式更有意义。更一般地说,显然如果你要缓存任何内容,最有效的方法是将结果缓存到处理缓存密钥不变的处理中。
请注意,CLR 缓存dynamic
类型对象的运行时成员解析。如果你不想自己搞乱缓存的实现,你可以将dynamic
合并到表达式中,让CLR处理动态命名方法的缓存。同样,如果没有您特定场景的更多详细信息,则无法确定这是否有效,更不用说它是否适用于您的情况。