4

I have been reading up on virtual methods and how they are called. As discussed here and here, I have reached the conclusion that they should not really be that different.

The C# compiler emits IL code that calls static methods by the call IL instruction and calls virtual/non-virtual members by callvirt. It seems it is the job of JIT to actually figure out if the object the method being called from is actually null or not. So the check is the same for both.

Also, as discussed in the first article, it seems that vtables or tables that hold metadata on method definitions, are flattened at compile time. In other words, the tables contain exactly which method the object should call without a need for a recursive search up the inheritance chain.

With all the above, why are virtual methods considered slower? Is maybe one level of indirection(if any)that big of a deal? Please explain...

Community
  • 1
  • 1
Farhad Alizadeh Noori
  • 2,276
  • 17
  • 22
  • *The CLR only calls static methods by the call IL instruction* is misleading. It is the C# compiler which emits the `call` instruction for static and `callvirt` for instance methods. Other compilers are free to implement it in their own way. CLR has nothing to do with this. – Sriram Sakthivel Oct 09 '14 at 15:14
  • @SriramSakthivel True. I'll rephrase. – Farhad Alizadeh Noori Oct 09 '14 at 15:15
  • Related : http://stackoverflow.com/questions/530799/what-are-the-performance-implications-of-marking-methods-properties-as-virtual – Sriram Sakthivel Oct 09 '14 at 15:28

2 Answers2

1

Figuring out which actual method implementation to execute is going to have some cost, as opposed to just knowing. That cost can be very small, and it is quite likely that the cost is entirely negligible for any particular context because it really doesn't take that long. But the cost is non-zero, so in particularly performance sensitive applications it will make some difference.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • Finding the actual implementation is against the claim that vtables are flattened in compile time. So do you believe that CLR still has to follow the inheritance chain? If not and if you are commenting on the actual `method table` in the metadata of the `type object` referenced by the object, isn't this the same case for non-virtual methods? In other words, isn't the right offset recorded in the method table slot for any given type at compile time(flattened vtables)? – Farhad Alizadeh Noori Oct 09 '14 at 15:22
  • @FarhadAliNoo If the method is virtual the actual runtime type of the objects needs to be checked and the implementation of the given method for that type needs to be looked up in the vtable. Neither of those needs to happen for a non-virtual method; the method is bound at compile time. – Servy Oct 09 '14 at 15:26
1

You're looking at the difference between a function call instruction with direct vs indirect addressing. But most of the "cost" of an indirect function call is not the call itself, but the lost opportunity to perform optimizations which require static knowledge of the target. Inlining, cross-procedure aliasing analysis, and so on.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720