【问题标题】:why invoking a method by reflection through an interface is much faster为什么通过接口通过反射调用方法要快得多
【发布时间】:2011-12-18 08:54:33
【问题描述】:

为什么通过反射调用方法比创建接口然后通过反射调用它要慢得多。第一个版本显示繁琐的方式另一个版本显示增强的方式??

 // first version
  class A
    {
        public void fn()
        { 
        }
    }
  void Main(String[]x)
  {
        Type type = typeof(A);
        object obj = Activator.CreateInstance(type);
        type.InvokeMember("fn", BindingFlags.Public, null, obj, null);
  }

  //second verison
   interface IA
    {
        void fn();
    }

    class A :IA
    {
        public void fn()
        {
        }
    }

 void Main(String []x)
 {
        Type type = typeof(A);
        IA obj =(IA) Activator.CreateInstance(type);
        obj.fn();
 }

【问题讨论】:

  • 您没有在第二个示例中反映方法调用;您所做的只是正常调用一个方法。此外,您没有提供任何基准。

标签: c# reflection interface


【解决方案1】:

基于反射的方法调用非常慢,因为您需要在运行时进行成员查找和参数绑定等操作。

相比之下,接口方法是通过使用 vtable 的常规 callvirt 指令调用的。

【讨论】:

  • invoke menber方法用的是哪个方法呢?
  • InvokeMember,与Type 类的其余部分一样,是反射。
【解决方案2】:

对于苹果与苹果的比较,调用 Type.GetConstructor 来获取一个 ConstructorInfo 对象并调用它来创建您的对象。然后,您可以保留 ConstructorInfo 并重用。相比之下,Activator 很慢。

回答您关于反射方式如何工作的问题:

Activator 在已加载程序集的元数据中搜索与您指定的类型名称相匹配的类型名称。然后它搜索类似于 Type.GetConstructor 的构造函数,该构造函数返回一个 ConstructorInfo。它调用该构造函数并返回对象。

然后当您调用 Type.InvokeMember 时,您再次使用反射,查询类的元数据以找到匹配的方法签名。这作为 MethodInfo 返回,然后被调用。

反射中的艰苦工作不是调用本身,而是元数据搜索类型、构造函数和方法。这就是为什么我说您可以通过重用 ConstructorInfo 和 MethodInfo 对象来对反射对象进行相对高性能的方法调用。你会发现重复调用 MethodInfo.Invoke 比 Type.InvokeMember 快很多

【讨论】:

  • 我不同意。如果将 Activator 调用和 invoke 成员调用分解为它们的实际实现,则涉及获取 ContructorInfo 和 MethodInfo。不需要 MethodInfo 查找的接口使用或静态方法调用
猜你喜欢
  • 2016-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
  • 2020-02-06
  • 1970-01-01
  • 2010-09-09
相关资源
最近更新 更多