【问题标题】:InvokeMember is very slow, anyway to avoid this?InvokeMember 很慢,无论如何要避免这种情况?
【发布时间】:2010-10-18 18:12:06
【问题描述】:

我必须进行反射和后期绑定,所以我不知道是否有办法加快速度。 以为我会试一试。

这个 sn-p 大约需要 15 秒才能完成,这太慢了,但是看看我需要如何读取元数据。

private static object InvokeCall(Type HostObjectType, Object HostObject, CallType callType, string PropertyOrMethodName, object[] args)
{
    if (callType == CallType.Method)
    {
        return MyObjectType.InvokeMember(PropertyOrMethodName,System.Reflection.BindingFlags.InvokeMethod, null, myObject, args);
    }
}

【问题讨论】:

  • 对 InvokeMember 的 single 调用绝对不会 花费 15 秒的反射开销。您是否反复调用InvokeCall?否则,到目前为止,最可能的解释是,无论您实际调用什么方法都需要一段时间,您应该调查那里的问题。
  • 这种特定方法在早期绑定时执行起来有多慢?
  • @Kirk 啊,是的,之后它调用了一个相当大的方法,虽然它不会让我介入,我会再研究一下

标签: c# winforms performance reflection late-binding


【解决方案1】:

看看Fasterflect - A Fast and Simple Reflection APIFast Invoker,他们已经准备好使用解决方案,并且值得学习。

如果你想走自己的路,请查看文章:Dodge Common Performance Pitfalls to Craft Speedy ApplicationsDynamically Compiled Lambdas vs. Pure Reflection

【讨论】:

【解决方案2】:

我假设 15s 是在循环中使用时;反射并没有那么慢。

您可以通过获取 MethodInfo 并使用 Delegate.CreateDelegate 一次来加快反射(尤其是调用)。然后,您缓存并重新使用生成的 typed 委托(匹配预期的调用签名)。然后使用类型化委托 Invoke。

注意无类型委托调用很慢;必须输入。还;如果您需要在每次调用时更改目标对象,您可以偷偷摸摸地使用带有额外(前导)参数的委托来针对一系列不同对象调用 instance 方法。

对于更复杂的场景,Expression 或 DynamicMethod 很有用。

【讨论】:

    【解决方案3】:

    尝试使用表达式树编译的 lambda 并缓存 lambda。我已广泛利用这一点并取得了巨大成功。

    http://kohari.org/2009/03/06/fast-late-bound-invocation-with-expression-trees/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-14
      • 1970-01-01
      相关资源
      最近更新 更多