代码之家  ›  专栏  ›  技术社区  ›  david.pfx

加快对MethodInfo的调用

  •  1
  • david.pfx  · 技术社区  · 9 年前

    许多代码只涉及推送和弹出堆栈值,但主要是函数调用。目前,函数调用的实现如下所示:

          var calli = gencode[pc++] as CallInfo;
          var calla = PopStackList(calli.NumArgs).ToArray();
          var ret = calli.MethodInfo.Invoke(instance, calla);
          if (ret != null) PushStack(ret);
    

    传递和返回的所有数据项都是使用自定义类型系统的对象(未使用本机类型)。澄清:这是一个实例方法,不是静态的。

    MethodInfo.Invoke 速度相当慢。问题是如何以尽可能高的速度进行函数调用,可能需要在编译器中做更多的准备工作并生成更好的代码。


    我看到投票结束,但在我看来,这个问题一点也不宽泛。编译器应该如何在虚拟机中实现对实例方法的函数调用以获得最佳性能,至少要比 MethodInfo.Invoke() ?

    2 回复  |  直到 9 年前
        1
  •  2
  •   Soonts    9 年前

    好吧,如果你确定你的主要问题是MethodInfo。援引

    将该表达式编译为 Action<tInstance, tArgs[]> (不知道你的类型)。

    将该操作缓存在CallInfo类实例中。

        2
  •  1
  •   Viking    7 年前

    通常,当您使用反射调用方法时,您会调用MethodInfo。援引不幸的是,这证明相当缓慢。如果在编译时知道方法的签名,可以使用delegate将方法转换为具有该签名的委托。CreateDelegate(类型、对象、方法信息)。只需传入要创建实例的委托类型、调用的目标(即将调用什么方法)和要调用的方法。如果这个调用有一个通用版本来避免抛出结果,那就太好了,不过没关系。下面是一个完整的示例,演示其工作原理:

    using System;
    using System.Reflection;
    public class Test
    {
        static void Main()
        {
            MethodInfo method = (string).GetMethod(“IndexOf”, new Type[]{typeof(char)});
    
            Func<char, int> converted = (Func<char, int>) 
    Delegate.CreateDelegate(typeof(Func<char, int>), “Hello”, method);
    
            Console.WriteLine(converted(‘l’));
            Console.WriteLine(converted(‘o’));
            Console.WriteLine(converted(‘x’));
        }
    }
    

    这将打印出2、4和-1;如果我们叫“你好”,我们会得到什么。索引(…)直接地现在让我们看看速度差异是什么

    我们最感兴趣的是从主调用代码到被调用方法所花费的时间,无论是直接方法调用MethodInfo。调用或委托。为了使IndexOf本身花费尽可能少的时间,我通过传递H来测试它,使其立即返回0。正常情况下,测试很粗糙,但结果如下:

    直接0.18 反射120

    复制自: https://blogs.msmvps.com/jonskeet/2008/08/09/making-reflection-fly-and-exploring-delegates/