gpt4 book ai didi

c# - 直接调用委托(delegate)、使用 DynamicInvoke 和使用 DynamicInvokeImpl 之间有什么区别?

转载 作者:IT王子 更新时间:2023-10-29 04:16:08 26 4
gpt4 key购买 nike

DynamicInvoke 和 DynamicInvokeImpl 的文档说:

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

我注意到 DynamicInvoke 和 DynamicInvokeImpl 采用对象数组而不是特定的参数列表(我猜这是后期绑定(bind)部分)。但这是唯一的区别吗? DynamicInvoke 和 DynamicInvokeImpl 之间有什么区别。

最佳答案

直接调用它(Invoke(...) 的简写)和使用 DynamicInvoke 的主要区别在于性能;根据我的测量(下图),该系数超过 *700。

使用直接/Invoke 方法,参数已经通过方法签名进行了预验证,并且代码已经存在以将它们直接传递到方法中(我会说“作为 IL”,但我似乎记得运行时直接提供了这个,没有任何 IL)。对于 DynamicInvoke,它需要通过反射从数组中检查它们(即它们是否都适合此调用;它们是否需要拆箱等);这是(如果您在紧密循环中使用它),应尽可能避免。

例子;首先是结果(我增加了之前编辑的 LOOP 计数,以进行合理的比较):

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");
}

关于c# - 直接调用委托(delegate)、使用 DynamicInvoke 和使用 DynamicInvokeImpl 之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/932699/

26 4 0
文章推荐: c# - 在 ASP.NET MVC 中将多个参数传递给 Controller ​​;此外,在 LINQ-to-SQL 中生成即时查询
文章推荐: javascript - 无法在