什么是直接调用的委托,采用DynamicInvoke,并使用DynamicInvokeImpl之间的区别? [英] What is the difference between calling a delegate directly, using DynamicInvoke, and using DynamicInvokeImpl?

查看:176
本文介绍了什么是直接调用的委托,采用DynamicInvoke,并使用DynamicInvokeImpl之间的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为DynamicInvoke和DynamicInvokeImpl文档说:

The docs for both DynamicInvoke and DynamicInvokeImpl say:

动态调用所代表(后期绑定)的
法目前的
代表。

Dynamically invokes (late-bound) the method represented by the current delegate.

我注意到,DynamicInvoke和DynamicInvokeImpl采取的对象,而不是参数的具体名单的数组(是我猜的后期绑定的一部分)。但是,这是唯一的区别?而这也正是DynamicInvoke和DynamicInvokeImpl之间的差异。

I notice that DynamicInvoke and DynamicInvokeImpl take an array of objects instead of a specific list of arguments (which is the late-bound part I'm guessing). But is that the only difference? And what is the difference between DynamicInvoke and DynamicInvokeImpl.

推荐答案

直接调用它(这是短手之间的主要区别调用(...)),并使用 DynamicInvoke 是性能;超过* 700我的措施(下图)的一个因素。

The main difference between calling it directly (which is short-hand for Invoke(...)) and using DynamicInvoke is performance; a factor of more than *700 by my measure (below).

通过直接/ 调用办法,参数已经通过方法签名预先验证,并且代码已经存在这些信息传递到直接的方法(我会说:作为IL,但我似乎记得,运行时直接提供这个,的没有的IL)。随着 DynamicInvoke ,它需要通过反射从数组检查它们(即是他们都适合这个呼叫,他们需要拆箱等);这就是(如果你正在使用它在一个紧密的循环),并应尽量避免使用。

With the direct/Invoke approach, the arguments are already pre-validated via the method signature, and the code already exists to pass those into the method directly (I would say "as IL", but I seem to recall that the runtime provides this directly, without any IL). With DynamicInvoke it needs to check them from the array via reflection (i.e. are they all appropriate for this call; do they need unboxing, etc); this is slow (if you are using it in a tight loop), and should be avoided where possible.

为例。结果第一个(我增加了 LOOP 从以前的编辑算,给一个合理的比较):

Example; results first (I increased the LOOP count from the previous edit, to give a sensible comparison):

Direct: 53ms
Invoke: 53ms
DynamicInvoke (re-use args): 37728ms
DynamicInvoke (per-cal args): 39911ms

通过代码:

static void DoesNothing(int a, string b, float? c) { }
static void Main() {
    Action<int, string, float?> method = DoesNothing;

    int a = 23;
    string b = "abc";
    float? c = null;
    const int LOOP = 5000000;

    Stopwatch watch = Stopwatch.StartNew();
    for (int i = 0; i < LOOP; i++) {
        method(a, b, c);
    }
    watch.Stop();
    Console.WriteLine("Direct: " + watch.ElapsedMilliseconds + "ms");

    watch = Stopwatch.StartNew();
    for (int i = 0; i < LOOP; i++) {
        method.Invoke(a, b, c);
    }
    watch.Stop();
    Console.WriteLine("Invoke: " + watch.ElapsedMilliseconds + "ms");

    object[] args = new object[] { a, b, c };
    watch = Stopwatch.StartNew();
    for (int i = 0; i < LOOP; i++) {
        method.DynamicInvoke(args);
    }
    watch.Stop();
    Console.WriteLine("DynamicInvoke (re-use args): "
         + watch.ElapsedMilliseconds + "ms");

    watch = Stopwatch.StartNew();
    for (int i = 0; i < LOOP; i++) {
        method.DynamicInvoke(a,b,c);
    }
    watch.Stop();
    Console.WriteLine("DynamicInvoke (per-cal args): "
         + watch.ElapsedMilliseconds + "ms");
}

这篇关于什么是直接调用的委托,采用DynamicInvoke,并使用DynamicInvokeImpl之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆