我阅读了this帖子,我尝试做同样的事情但是在比较del.DynamicINvoke(args)V时我遇到了一个非常奇怪的行为。德尔(参数)
更新
所以在Jon和usr评论之后我发布了新的工作代码。
我真的很感激任何帮助!
代码:
using System;
using System.Diagnostic;
using System.Threading;
namespace DynamicInvokeVsInvoke {
public class Program {
static void Main(string[] args) {
var objArgs = new object[] {100, 1.2345678 };
Action<int, double> a = (i, d) => {};
Action<object[]> action = o => a((int)o[0], (double)o[1]);
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
a.DynamicInvoke(objArgs);
Console.WriteLine("Dynamic: " + sw.ElapsedMilliseconds);
sw.Stop();
sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
action(objArgs);
Console.WriteLine("Invoke: " + sw.ElapsedMilliseconds);
sw.Stop();
}
}
}
结果:
当'a'为空方法并且循环运行1000000次时,DynamicInvoke大约需要4000毫秒,直接调用需要20毫秒
当我放入Thread.Sleep(20)并且循环运行1000次时,DynamicInvoke和直接调用大约需要20秒
P.S。我出于某种原因无法从vs复制/粘贴所以我手动编写代码如果你看到语法错误请告诉我
答案 0 :(得分:1)
首先要注意的是:在查看性能时,请始终确保您正在运行发布/优化版本,然后运行而不使用 IDE。您通常可以在Visual Studio中使用 ctrl + f5 ,但如果有疑问:从命令行运行它。
当'a'为空方法并且循环运行1000000次时,DynamicInvoke大约需要4000毫秒,直接调用需要20毫秒
足够公平; DynamicInvoke
获得2729ms,直接调用获得8ms;但这就是我们所期望的;我们知道 DynamicInvoke
速度较慢。但是这里的一切都如我们所料。事实上,如果我们纠正Invoke
不公平地运行委托调用的额外级别这一事实(我们应该将所需的时间大致加倍),我们得到:
static void Main()
{
int x = 100;
double y = 1.2345678;
var objArgs = new object[] { x, y };
Action<int, double> a = (i, d) => { };
var sw = new Stopwatch();
sw.Start();
const int loop = 1000000;
for (int i = 0; i < loop; i++)
a.DynamicInvoke(objArgs);
Console.WriteLine("Dynamic: " + sw.ElapsedMilliseconds);
sw.Stop();
sw = new Stopwatch();
sw.Start();
for (int i = 0; i < loop; i++)
a(x,y);
Console.WriteLine("Invoke: " + sw.ElapsedMilliseconds);
sw.Stop();
}
结果:
Dynamic: 2785
Invoke: 3
到目前为止,没有任何意外。
当我放入Thread.Sleep(20)并且循环运行1000次时,DynamicInvoke和直接调用大约需要20秒
是的,20ms x 1000绝对是20秒。 20毫秒的睡眠时间并不准确;我们期望在该数字周围出现一些差异,当乘以1000时会增加。特别是,睡眠中断不会在每个CPU周期中触发,所以我们应该期待稍微不规则的睡眠周期吃掉Invoke
和DynamicInvoke
之间的差异(每次通话大约2.75微秒)。
将loop
更改为1000并添加Thread.Sleep(20)
我得到:
Dynamic: 20395
Invoke: 20370
再一次,这里没什么可惊讶的。实际上,由于Thread.Sleep()
引入的轻微随机性乘以1000,如果Invoke
偶尔花费的时间超过Dynamic
,我会觉得完全可以接受。
在数字中我没有看到任何令人惊讶的东西。
答案 1 :(得分:0)
您的测量设置中存在一些产生系统错误的信息。当然,您不会认为使用DynamicInvoke会更快地调用委托的 body 。它对身体没有影响。