- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
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/
DynamicInvoke 和 DynamicInvokeImpl 的文档说: Dynamically invokes (late-bound) the method represented by t
我是一名优秀的程序员,十分优秀!