I read this post and I tried to do the same but I came across a very strange behavior when comparing the del.DynamicINvoke(args) Vs. del(args)
Update
So after Jon and usr comments i post now new working code.
I'll really appreciate any help!
Code:
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();
}
}
}
Results:
When 'a' is empty method and the loop runs 1000000 times the DynamicInvoke took approximately 4000 ms and the direct Invoke took 20 ms
When i'm put in a Thread.Sleep(20) and the loop runs 1000 times then the DynamicInvoke and the direct Invoke took approximately 20 seconds
p.s. i can't copy/paste from vs for some reason so i write the code manually if you see syntax error please let me know
First thing to note: when looking at performance always ensure you are running a release/optimized build, and run it without the IDE attached. You can usually get away with ctrl+f5 in Visual Studio, but if in doubt: run it from the command line.
Fair enough; I get 2729ms for
DynamicInvoke
and 8ms for direct invoke; but that is what we expect; we know thatDynamicInvoke
is slower. But everything here is as we expect. In fact, if we correct for the fact thatInvoke
is unfairly running an extra level of delegate invoke (which we should expect to roughly-double the time taken), we get:with results:
So far, nothing unexpected.
Yep, 20ms x 1000 is definitely 20 seconds. The 20ms sleep time is not exact; we expect some variance around that number, which adds up when multiplied by 1000. In particular, the sleep interrupt isn't going to fire for every single CPU cycle, so we should probably expect the slightly irregular sleep cycle to eat up the difference between a
Invoke
andDynamicInvoke
(about 2.75 microseconds per call).Changing
loop
to 1000 and adding aThread.Sleep(20)
I get:Again, nothing surprising here. In fact, with the slight randomness introduced by a
Thread.Sleep()
, multiplied by 1000 I would find it perfectly acceptable ifInvoke
occasionally took longer thanDynamic
.I see nothing in the least bit surprising in the numbers.