我应该做些什么来制作高性能且强大的反射缓存?

时间:2008-10-11 08:56:39

标签: c# .net reflection caching

在.NET 3.5中,我将使用System.Reflection来使用AOP(可能在Castle的Windsor Interceptors的上下文中)来执行诸如定义需要在方法级别执行哪些安全操作等操作,等等我听说反射的某些部分很慢(我已经读过它周围的MSDN文章),并希望缓存这些部分(当我接近生产代码时,无论如何)。我想验证我的方法:

  • 缓存键为{type} + {区分大小写的方法名称} + {list of parameters types}
  • 可以通过Equals操作
  • 比较缓存关键对象
  • 缓存有效负载是{MethodInfo} + {在方法上定义的自定义属性列表}
  • 缓存通过构造函数注入
  • 注入到我的拦截器中
  • 缓存可以维持很长时间(基于我不打算编写自修改代码的假设;-))

更新

我不打算通过反思来调用我自己写的东西;只是(此时)查找我想要注入功能的属性,其中属性定义要注入的行为。我的拦截器目前将使用Castle的Windsor IInterceptor机制,直到我发现有理由改变它。

2 个答案:

答案 0 :(得分:3)

显式调用MethodInfo确实很慢 - 但如果将其转换为委托,则可以使其更快,更多。例如,请参阅this blog post。当然,这对找到方法等没有帮助,但是如果你要反复调用这个方法,那么值得记住。

缓存键听起来很容易构建 - 类型和字符串比较好且容易。值总是相对简单:)

一旦构建,缓存是否为只读?你能否将阶段分开,以便保证在完全建成之前不会被阅读?如果是这样,你应该能够在没有任何明确锁定的情况下离开 - 基本上是从自定义键类型到自定义值类型的字典。

答案 1 :(得分:1)

我同意Jon的大部分帖子 - 字典中的一个小注释:从性能角度来看,你可能想要对这个仅仅是一个平面列表进行基准测试。上次我做了一个基准测试(字典与平面列表,检查每个项目,直到找到匹配),分割点(读取访问)大约是150个项目;在下面,列表更快(只是简单)。但是做你自己的测试......(我没有数字可以证明这种或那种方式)。

根据代码的不同,您可能可以使用泛型来进一步拆分数据 - 即Cache,以便T类型的所有信息都在一个地方,填充在Cache的静态ctor中。根据架构的不同,这可能是也可能是不可能的。

最后,它可能适合也可能不适合,但是现有的AOP框架(如PostSharp)可能有助于简化注入点。

重新说明一点 - 在(在你的初始化代码中)为Cache方法上的方法创建一个类型化的委托是相当容易的,以减少它需要扫描的数据量 - 只需要一点Type。 MakeGenericType和Delegate.CreateDelegate - 在此之后,代码只知道你的Func< ...>委托,并不需要关心实施。