Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I did some tests (in .Net 3.5... later I will check at home using .Net 4). The fact is: Getting an object as an interface and then executing the method is faster than getting a delegate from a method then calling the delegate.</p> <p>Considering the variable is already in the right type (interface or delegate) and simple invoking it makes the delegate win.</p> <p>For some reason, getting a delegate over an interface method (maybe over any virtual method) is MUCH slower.</p> <p>And, considering there are cases when we simple can't pre-store the delegate (like in Dispatches, for example), that may justify why interfaces are faster.</p> <p>Here are the results:</p> <p>To get real results, compile this in Release mode and run it outside Visual Studio.</p> <blockquote> <p>Checking direct calls twice<br> 00:00:00.5834988<br> 00:00:00.5997071</p> <p>Checking interface calls, getting the interface at every call<br> 00:00:05.8998212</p> <p>Checking interface calls, getting the interface once<br> 00:00:05.3163224</p> <p>Checking Action (delegate) calls, getting the action at every call<br> 00:00:17.1807980</p> <p>Checking Action (delegate) calls, getting the Action once<br> 00:00:05.3163224</p> <p>Checking Action (delegate) over an interface method, getting both at every call<br> 00:03:50.7326056</p> <p>Checking Action (delegate) over an interface method, getting the interface once, the delegate at every call<br> 00:03:48.9141438</p> <p>Checking Action (delegate) over an interface method, getting both once<br> 00:00:04.0036530</p> </blockquote> <p>As you can see, the direct calls are really fast. Storing the interface or delegate before, and then only calling it is really fast. But having to get a delegate is slower than having to get an interface. Having to get a delegate over an interface method (or virtual method, not sure) is really slow (compare the 5 seconds of getting an object as an interface to the almost 4 minutes of doing the same to get the action).</p> <p>The code that generated those results is here:</p> <pre><code>using System; namespace ActionVersusInterface { public interface IRunnable { void Run(); } public sealed class Runnable: IRunnable { public void Run() { } } class Program { private const int COUNT = 1700000000; static void Main(string[] args) { var r = new Runnable(); Console.WriteLine("To get real results, compile this in Release mode and"); Console.WriteLine("run it outside Visual Studio."); Console.WriteLine(); Console.WriteLine("Checking direct calls twice"); { DateTime begin = DateTime.Now; for (int i = 0; i &lt; COUNT; i++) { r.Run(); } DateTime end = DateTime.Now; Console.WriteLine(end - begin); } { DateTime begin = DateTime.Now; for (int i = 0; i &lt; COUNT; i++) { r.Run(); } DateTime end = DateTime.Now; Console.WriteLine(end - begin); } Console.WriteLine(); Console.WriteLine("Checking interface calls, getting the interface at every call"); { DateTime begin = DateTime.Now; for (int i = 0; i &lt; COUNT; i++) { IRunnable interf = r; interf.Run(); } DateTime end = DateTime.Now; Console.WriteLine(end - begin); } Console.WriteLine(); Console.WriteLine("Checking interface calls, getting the interface once"); { DateTime begin = DateTime.Now; IRunnable interf = r; for (int i = 0; i &lt; COUNT; i++) { interf.Run(); } DateTime end = DateTime.Now; Console.WriteLine(end - begin); } Console.WriteLine(); Console.WriteLine("Checking Action (delegate) calls, getting the action at every call"); { DateTime begin = DateTime.Now; for (int i = 0; i &lt; COUNT; i++) { Action a = r.Run; a(); } DateTime end = DateTime.Now; Console.WriteLine(end - begin); } Console.WriteLine(); Console.WriteLine("Checking Action (delegate) calls, getting the Action once"); { DateTime begin = DateTime.Now; Action a = r.Run; for (int i = 0; i &lt; COUNT; i++) { a(); } DateTime end = DateTime.Now; Console.WriteLine(end - begin); } Console.WriteLine(); Console.WriteLine("Checking Action (delegate) over an interface method, getting both at every call"); { DateTime begin = DateTime.Now; for (int i = 0; i &lt; COUNT; i++) { IRunnable interf = r; Action a = interf.Run; a(); } DateTime end = DateTime.Now; Console.WriteLine(end - begin); } Console.WriteLine(); Console.WriteLine("Checking Action (delegate) over an interface method, getting the interface once, the delegate at every call"); { DateTime begin = DateTime.Now; IRunnable interf = r; for (int i = 0; i &lt; COUNT; i++) { Action a = interf.Run; a(); } DateTime end = DateTime.Now; Console.WriteLine(end - begin); } Console.WriteLine(); Console.WriteLine("Checking Action (delegate) over an interface method, getting both once"); { DateTime begin = DateTime.Now; IRunnable interf = r; Action a = interf.Run; for (int i = 0; i &lt; COUNT; i++) { a(); } DateTime end = DateTime.Now; Console.WriteLine(end - begin); } Console.ReadLine(); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload