title: Why is there such a large difference in the performance of different ways to pass delegates?
body: <p>I was attempting to compare three different ways of passing a delegate to a function in C# -- by lambda, by delegate, and by direct reference.  What really surprised me was the direct reference method (i.e. <code>ComputeStringFunctionViaFunc(object[i].ToString))</code> was six times slower than the other methods.  Does anyone know why this is?</p>
  
  <p>The complete code is as below:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Runtime.CompilerServices;
  
  namespace FunctionInvocationTest
  {
      class Program
      {
          static void Main(string[] args)
          {
              object[] objectArray = new object[10000000];
              for (int i = 0; i &lt; objectArray.Length; ++i) { objectArray[i] = new object(); }
  
              ComputeStringFunction(objectArray[0]);
              ComputeStringFunctionViaFunc(objectArray[0].ToString);
              ComputeStringFunctionViaFunc(delegate() { return objectArray[0].ToString(); });
              ComputeStringFunctionViaFunc(() =&gt; objectArray[0].ToString());
  
              System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
              s.Start();
              for (int i = 0; i &lt; objectArray.Length; ++i)
              {
                  ComputeStringFunction(objectArray[i]);
              }
              s.Stop();
              Console.WriteLine(s.Elapsed.TotalMilliseconds);
  
              s.Reset();
              s.Start();
              for (int i = 0; i &lt; objectArray.Length; ++i)
              {
                  ComputeStringFunctionViaFunc(delegate() { return objectArray[i].ToString(); });
              }
              s.Stop();
              Console.WriteLine(s.Elapsed.TotalMilliseconds);
  
              s.Reset();
              s.Start();
              for (int i = 0; i &lt; objectArray.Length; ++i)
              {
                  ComputeStringFunctionViaFunc(objectArray[i].ToString);
              }
              s.Stop();
              Console.WriteLine(s.Elapsed.TotalMilliseconds);
  
              s.Reset();
              s.Start();
              for (int i = 0; i &lt; objectArray.Length; ++i)
              {
                  ComputeStringFunctionViaFunc(() =&gt; objectArray[i].ToString());
              }
              s.Stop();
              Console.WriteLine(s.Elapsed.TotalMilliseconds);
  
              Console.ReadLine();
          }
  
          [MethodImpl(MethodImplOptions.NoInlining)]
          public static void ComputeStringFunction(object stringFunction)
          {
          }
  
          public static void ComputeStringFunctionViaFunc(Func&lt;string&gt; stringFunction)
          {
          }
      }
  }
  </code></pre>