Performance of calling delegates vs methods

c# delegate vs func performance
why delegates why not call methods directly
delegate method
when to use delegates instead of interfaces
c# func performance
advantages of events over delegates in c#
c# delegate interface
reflection vs delegate

Following this question - Pass Method as Parameter using C# and some of my personal experience I'd like to know a little more about the performance of calling a delegate vs just calling a method in C#.

Although delegates are extremely convenient, I had an app that did lots of callbacks via delegates and when we rewrote this to use callback interfaces we got an order of magnitude speed improvement. This was with .NET 2.0 so I'm not sure how things have changed with 3 and 4.

How are calls to delegates handled internally in the compiler/CLR and how does this affect performance of method calls?


EDIT - To clarify what I mean by delegates vs callback interfaces.

For asynchronous calls my class could provide an OnComplete event and associated delegate which the caller could subscribe to.

Alternatively I could create an ICallback interface with an OnComplete method that the caller implements and then registers itself with the class that will then call that method on completion (i.e. the way Java handles these things).

I haven't seen that effect - I've certainly never encountered it being a bottleneck.

Here's a very rough-and-ready benchmark which shows (on my box anyway) delegates actually being faster than interfaces:

using System;
using System.Diagnostics;

interface IFoo
{
    int Foo(int x);
}

class Program : IFoo
{
    const int Iterations = 1000000000;

    public int Foo(int x)
    {
        return x * 3;
    }

    static void Main(string[] args)
    {
        int x = 3;
        IFoo ifoo = new Program();
        Func<int, int> del = ifoo.Foo;
        // Make sure everything's JITted:
        ifoo.Foo(3);
        del(3);

        Stopwatch sw = Stopwatch.StartNew();        
        for (int i = 0; i < Iterations; i++)
        {
            x = ifoo.Foo(x);
        }
        sw.Stop();
        Console.WriteLine("Interface: {0}", sw.ElapsedMilliseconds);

        x = 3;
        sw = Stopwatch.StartNew();        
        for (int i = 0; i < Iterations; i++)
        {
            x = del(x);
        }
        sw.Stop();
        Console.WriteLine("Delegate: {0}", sw.ElapsedMilliseconds);
    }
}

Results (.NET 3.5; .NET 4.0b2 is about the same):

Interface: 5068
Delegate: 4404

Now I don't have particular faith that that means delegates are really faster than interfaces... but it makes me fairly convinced that they're not an order of magnitude slower. Additionally, this is doing almost nothing within the delegate/interface method. Obviously the invocation cost is going to make less and less difference as you do more and more work per call.

One thing to be careful of is that you're not creating a new delegate several times where you'd only use a single interface instance. This could cause an issue as it would provoke garbage collection etc. If you're using an instance method as a delegate within a loop, you will find it more efficient to declare the delegate variable outside the loop, create a single delegate instance and reuse it. For example:

Func<int, int> del = myInstance.MyMethod;
for (int i = 0; i < 100000; i++)
{
    MethodTakingFunc(del);
}

is more efficient than:

for (int i = 0; i < 100000; i++)
{
    MethodTakingFunc(myInstance.MyMethod);
}

Could this have been the problem you were seeing?

When & why to use delegates?, NET runtime and whilst you rarely create them directly, they are there under-the-​hood every time Creation of the delegate Invoke() method. The Result Somewhat surprisingly, invoking delegates proved to be faster, averaging 269 ticks over 5 runs, where as invoking methods took an average of 365 ticks!

Since CLR v 2, the cost of delegate invocation is very close to that of virtual method invocation, which is used for interface methods.

See Joel Pobar's blog.

Why should I use delegates instead of directly invoking the method , To my mind, if using delegates complicates your code or make it less in performance between invoking a delegate and a method in C# 4. In performance terms, this compares pretty unfavourably against a plain old method call. Initial performance tests showed that 10,000,000 calls to SomePublicMethod above were taking over 12 seconds compared to calling the same method publicly (I setup stub methods to make the performance more measurable) which took less than 1/10 of a second.

I find it completely implausible that a delegate is substantially faster or slower than a virtual method. If anything the delegate should be negligibly faster. At a lower level, delegates are usually implemented something like (using C-style notation, but please forgive any minor syntax errors as this is just an illustration):

struct Delegate {
    void* contextPointer;   // What class instance does this reference?
    void* functionPointer;  // What method does this reference?
}

Calling a delegate works something like:

struct Delegate myDelegate = somethingThatReturnsDelegate();
// Call the delegate in de-sugared C-style notation.
ReturnType returnValue = 
    (*((FunctionType) *myDelegate.functionPointer))(myDelegate.contextPointer);

A class, translated to C, would be something like:

struct SomeClass {
    void** vtable;        // Array of pointers to functions.
    SomeType someMember;  // Member variables.
}

To call a vritual function, you would do the following:

struct SomeClass *myClass = someFunctionThatReturnsMyClassPointer();
// Call the virtual function residing in the second slot of the vtable.
void* funcPtr = (myClass -> vtbl)[1];
ReturnType returnValue = (*((FunctionType) funcPtr))(myClass);

They're basically the same, except that when using virtual functions you go through an extra layer of indirection to get the function pointer. However, this extra indirection layer is often free because modern CPU branch predictors will guess the address of the function pointer and speculatively execute its target in parallel with looking up the address of the function. I've found (albeit in D, not C#) that virtual function calls in a tight loop are not any slower than non-inlined direct calls, provided that for any given run of the loop they're always resolving to the same real function.

When to Use Delegates Instead of Interfaces in C, Method calls. Does anyone please let me know, why delegates are mostly used than methods and does delegates increases performance ? Why couldn’t you just directly call a method on an object instead of using a delegate? Without Delegates. Let’s see what directly calling methods on objects looks like so we can see how delegates improves this. I’m going to use an example from the video C# Design Patterns with Jon Skeet: Outtakes where Mr. Skeet implements the Decorator

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.

Considering the variable is already in the right type (interface or delegate) and simple invoking it makes the delegate win.

For some reason, getting a delegate over an interface method (maybe over any virtual method) is MUCH slower.

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.

Here are the results:

To get real results, compile this in Release mode and run it outside Visual Studio.

Checking direct calls twice 00:00:00.5834988 00:00:00.5997071

Checking interface calls, getting the interface at every call 00:00:05.8998212

Checking interface calls, getting the interface once 00:00:05.3163224

Checking Action (delegate) calls, getting the action at every call 00:00:17.1807980

Checking Action (delegate) calls, getting the Action once 00:00:05.3163224

Checking Action (delegate) over an interface method, getting both at every call 00:03:50.7326056

Checking Action (delegate) over an interface method, getting the interface once, the delegate at every call 00:03:48.9141438

Checking Action (delegate) over an interface method, getting both once 00:00:04.0036530

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).

The code that generated those results is here:

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 < COUNT; i++)
                {
                    r.Run();
                }
                DateTime end = DateTime.Now;
                Console.WriteLine(end - begin);
            }
            {
                DateTime begin = DateTime.Now;
                for (int i = 0; i < 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 < 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 < 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 < 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 < 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 < 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 < 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 < COUNT; i++)
                {
                    a();
                }
                DateTime end = DateTime.Now;
                Console.WriteLine(end - begin);
            }
            Console.ReadLine();
        }
    }

}

Delegates, If you can call a method directly, then you don't need a delegate. is not much of a difference: Performance of calling delegates vs methods? Compiling a lambda expression and running it is the slowest type of code invocation. There is not a meaningful difference between calling a static, instance, virtual method or Func/delegate. Calling a method on a dynamic object less than twice slower than making a direct call. Source code

What about the fact that delegates are containers? Doesn't the multicast ability add overhead? While we are on the subject, what if we push this container aspect a little further? Nothing forbids us, if d is a delegate, from executing d += d; or from building an arbitrarily complex directed graph of (context pointer, method pointer) pairs. Where can I find the documentation describing how this graph is traversed when the delegate is called?

How do .NET delegates work? · Performance is a Feature!, Invoke vs a Delegate. I recently had to use a bit of reflection to call a private method on a third party component (don't ask why, it's complicated  The ildasm shows that a direct call of function is performed with "call method" command, while call through event performed with "callvirt delegatename::Invoke()". May seem that direct call should be faster, but let's consider what is Invoke(). Invoke is not a member of Delegate or MulticastDelegate classes.

Performance Test – Delegates vs Methods, Related Posts: Bad Data, Try/Catch, and Slow Performance · Singleton Indexer - A Workaround for not having Static Indexers in C# · Calculating Values using  "Anonymous function" refers to either a lambda expression or an anonymous method (which is what you've called a "delegate" in your code). All three operations are using delegates. The second and third are both using lambda expressions. All three will execute in the same way, with the same performance characteristics.

Does using Delegate calls increases performance than using , Assign it once and you don't have to use an if over and over. The delegate approach using delegates as function pointers delegate void Del()  The parameters passed to the delegate by the caller are passed to the method, and the return value, if any, from the method is returned to the caller by the delegate. This is known as invoking the delegate. An instantiated delegate can be invoked as if it were the wrapped method itself. For example: C#.

Delegates vs Methods, November 30, 2015 Tags: delegate, invoke, performance call delegates like a function— del() —and others use the Invoke method of the Delegate class: del. A delegate call also involves an extra level of indirection. Calls to a delegate do not involve putting arguments in an array unless you are performing a dynamic invoke using the DynamicInvoke method. A delegate call involves the calling method calling a compiler generated Invoke method on the delegate type in question.

Comments
  • I'm not clear on what you're asking... callbacks interfaces are delegates.
  • See stackoverflow.com/questions/1269452/… and stackoverflow.com/questions/304770/… - possible duplicates?
  • delegate are necessary if you are running separate threads and need to interface with the UI thread.. so you need to refine your question more to be more localized and less generic.
  • Can you elaborate on what the compiler does in the last case? Does it create a new delegate instance on every iteration or?
  • Would this change if you turned it into an event using the delegate?
  • Thanks Jon, I don't think it was an excess of objects/garbage collection but your benchmark neatly shows that delegates are at least as fast so whatever the original cause I'll patch my internal knowledge with these results ;)
  • Whats about performance ? Action/Func are implemented as delegates. Delegates are implemented in IL as compiler-generated classes with an Invoke() method. Calling foo() when foo is a delegate actually compiles down to calling foo.Invoke(), which in turn calls the destination code. If foo is an actual method instead of a delegate, calling foo() calls directly to the destination code with no Invoke() intermediate. See ILDASM for proof. stackoverflow.com/a/8449833/206730
  • @Kiquenet: If you're using an interface or a virtual method as well, that introduces an extra level of indirection as well. Yes, you can get slightly better performance if you just invoke a non-virtual method directly, but it's rarely actually significant in my experience.
  • That was always my assumption until I came across the anomaly I described in the question. Maybe as Jon suggests something else was the problem and I've got stuck on a "delegates are slower" meme by mistake.
  • If only there were more truly technical answers like this on SO, showing how the underlying implementations were achieved, instead of expecting askers to rely on blind faith that "it is so".
  • You probably shouldn't include getting the delegate in the time it takes to run it.
  • Nice benchmarks, thank you. I tried a number of variations and determined that: direct calls are always the fastest; static direct calls are no faster than instance member direct calls; .NET 4 is slower for direct calls, though faster in some other cases; compiling with "/optimize+" helps, but "/debug-" and "/checked-" don't make any difference; "/platform:x64" doesn't affect timings, but "/platform:x86" does (faster in a couple cases, slower in most); separating tests into their own methods makes no difference; putting Runnable in a separate assembly makes no difference.
  • Wouldn't the Action class add some overhead?
  • Conceptually, there's no reason why support for multicast delegates would have to slow invocation in the single-target case. If delegates with multiple targets set their internal method pointer to a special ExecuteMultiDelegate method, and its internal target reference to an array of structs holding (Object,Method) pairs, delegates could dispatch unconditionally to their method without checking whether there were multiple targets. The ExecuteMultiDelegate method would have to have some of the normal type-check behavior disabled, but that should be doable.
  • Note that the approach I just described isn't AFAIK how MulticastDelegates are actually implemented, but it would be a mechanism for optimizing the most common (exactly one target) case.