title: Performance of "direct" virtual call vs. interface call in C#
body: <p><a href="http://pastebin.com/jx3W5zWb" rel="noreferrer">This benchmark</a> appears to show that calling a virtual method directly on object reference is faster than calling it on the reference to the interface this object implements.</p>
  
  <p>In other words:</p>
  
  <pre><code>interface IFoo {
      void Bar();
  }
  
  class Foo : IFoo {
      public virtual void Bar() {}
  }
  
  void Benchmark() {
      Foo f = new Foo();
      IFoo f2 = f;
      f.Bar(); // This is faster.
      f2.Bar();    
  }
  </code></pre>
  
  <p>Coming from the C++ world, I would have expected that both of these calls would be implemented identically (as a simple virtual table lookup) and have the same performance. How does C# implement virtual calls and what is this "extra" work that apparently gets done when calling through an interface?</p>
  
  <h2>--- EDIT ---</h2>
  
  <p>OK, answers/comments I got so far imply that there is a double-pointer-dereference for virtual call through interface versus just one dereference for virtual call through object.</p>
  
  <p>So could please somebody explain <strong>why</strong> is that necessary? What is the structure of the virtual table in C#? Is it "flat" (as is typical for C++) or not? What were the design tradeoffs that were made in C# language design that lead to this? I'm not saying this is a "bad" design, I'm simply curious as to why it was necessary.</p>
  
  <p>In a nutshell, I'd like to <strong>understand</strong> what my tool does under the hood so I can use it more effectively. And I would appreciate if I didn't get any more "you shouldn't know that" or "use another language" types of answers.</p>
  
  <h2>--- EDIT 2 ---</h2>
  
  <p>Just to make it clear we are not dealing with some compiler of JIT optimization here that removes the dynamic dispatch: I modified the benchmark mentioned in the original question to instantiate one class or the other randomly at run-time. Since the instantiation happens after compilation and after assembly loading/JITing, there is no way to avoid dynamic dispatch in both cases:</p>
  
  <pre><code>interface IFoo {
      void Bar();
  }
  
  class Foo : IFoo {
      public virtual void Bar() {
      }
  }
  
  class Foo2 : Foo {
      public override void Bar() {
      }
  }
  
  class Program {
  
      static Foo GetFoo() {
          if ((new Random()).Next(2) % 2 == 0)
              return new Foo();
          return new Foo2();
      }
  
      static void Main(string[] args) {
  
          var f = GetFoo();
          IFoo f2 = f;
  
          Console.WriteLine(f.GetType());
  
          // JIT warm-up
          f.Bar();
          f2.Bar();
  
          int N = 10000000;
          Stopwatch sw = new Stopwatch();
  
          sw.Start();
          for (int i = 0; i &lt; N; i++) {
              f.Bar();
          }
          sw.Stop();
          Console.WriteLine("Direct call: {0:F2}", sw.Elapsed.TotalMilliseconds);
  
          sw.Reset();
          sw.Start();
          for (int i = 0; i &lt; N; i++) {
              f2.Bar();
          }
          sw.Stop();
          Console.WriteLine("Through interface: {0:F2}", sw.Elapsed.TotalMilliseconds);
  
          // Results:
          // Direct call: 24.19
          // Through interface: 40.18
  
      }
  
  }
  </code></pre>
  
  <h2>--- EDIT 3 ---</h2>
  
  <p>If anyone is interested, here is how my Visual C++ 2010 lays out an instance of a class that multiply-inherits other classes:</p>
  
  <p>Code:</p>
  
  <pre><code>class IA {
  public:
      virtual void a() = 0;
  };
  
  class IB {
  public:
      virtual void b() = 0;
  };
  
  class C : public IA, public IB {
  public:
      virtual void a() override {
          std::cout &lt;&lt; "a" &lt;&lt; std::endl;
      }
      virtual void b() override {
          std::cout &lt;&lt; "b" &lt;&lt; std::endl;
      }
  };
  </code></pre>
  
  <p>Debugger:</p>
  
  <pre><code>c   {...}   C
      IA  {...}   IA
          __vfptr 0x00157754 const C::`vftable'{for `IA'} *
              [0] 0x00151163 C::a(void)   *
      IB  {...}   IB
          __vfptr 0x00157748 const C::`vftable'{for `IB'} *
              [0] 0x0015121c C::b(void)   *
  </code></pre>
  
  <p>Multiple virtual table pointers are clearly visible, and <code>sizeof(C) == 8</code> (in 32-bit build).</p>
  
  <p>The...</p>
  
  <pre><code>C c;
  std::cout &lt;&lt; static_cast&lt;IA*&gt;(&amp;c) &lt;&lt; std::endl;
  std::cout &lt;&lt; static_cast&lt;IB*&gt;(&amp;c) &lt;&lt; std::endl;
  </code></pre>
  
  <p>..prints...</p>
  
  <pre><code>0027F778
  0027F77C
  </code></pre>
  
  <p>...indicating that pointers to different interfaces within the same object actually point to different parts of that object (i.e. they contain different physical addresses).</p>