C# · CodeProject · Dotnet

Virtual Methods can cause performance overheads

Dear Reader,

Often we developers do not realize the pros and cons of a feature in a language. Yet we still do use at our wimps and fancies. Although at first you might think i am talking non-sense, but any good programmer should also think twice about a feature before accepting it for granted.

In this article, i shall talk about Virtual Methods in inheritance tree do cause performance overheads some times or when used extensively.

Even though you place override keyword in every method, internally the compiler converts all of them to virtual keyword. Hence at run time, the CLR has to execute one more instructure and has to look in method tables as which concrete types method has to be called.  This extra calculation or searching pattern do adds a bit of performance hit (Thanks to Qwertie for pointing the mistake). if it is done often by the CLR. Hence the virtual methods do not get inlined by the compiler.

Lets see a sample code:

As you can see from the above code, although it looks very simplistic in nature. There is a small trick w.r.t to this articles interests.

Lets see the main methods IL for a min:

As you can see from the IL in comparison with the Main() code, i have declared:

SecondChild d = new ThirdChild()

But in the IL, compiler is calling virtually Base.DoWork(). Since the run time see virtual keyword in the method definition so it tries to search the hierarchy in child classes from this base class. Such a way it traverse till the leaf node in the tree till it no more finds the overriding method/in other words another virtual method atleast in this example case. Other wise, it shall traverse till the RHS class encountered which is declared in the code i.e ThirdChild() here. Beyond, it does not care to search, since that’s how it has been declared in the code right.

In the above case, since the method in ThirdChild class has given a new definition, hence it hooks up the call for SecondChilds DoWork(). If you remove the new keyword from ThirdChild class DoWork(), and provide override keyword, then ThirdChild class method shall be called. Since its the most derived method available in the inheritance tree.

So now you might have understood how CLR runs through the whole long subclass tree structure. Hence its better to avoid too many virtual methods in your production code folks 🙂

Thanks 🙂

P.S: Your valuable comments/votes are well appreciated.

UPDATE:

One of the codeproject reader has requested me to provide a cost comparison. I wonder why i did not care/missed out to provide this information when i wrote the article. I apologize to all the readers for this mistake. So here i am providing the requested information:

So for the test purpose, i wrote the following code:

    class Base
{
public virtual void Hello() { }
}

class Child1 : Base
{
public override void Hello() { }
}
class Child2 : Child1
{
public override void Hello() { }
}

class Child3 : Child2
{
public override void Hello() { }
}

class SomeClass
{
public  void Hello() { }
}

sealed class Program
{
static void Main(string[] args)
{
Base b = new Child3();

Stopwatch sp = Stopwatch.StartNew();
b.Hello();
sp.Stop();
Console.WriteLine(sp.ElapsedTicks);

SomeClass c = new SomeClass();

sp = Stopwatch.StartNew();
c.Hello();
sp.Stop();
Console.WriteLine(sp.ElapsedTicks);
Console.ReadLine();
}

Now as per this code, the output you get in terms of ticks shows you the performance or inheritance call ticks is more than directly calling a method. The output is shown below:

144873
141984

Yes the difference is very less, but upon increasing the hierarchy as well as frequent usage, this difference grows. Even i checked JR book on the same and its true.

One more point worth mentioning here is, not only the virtual methods performance is slow, its also depends on how we use it. Thanks to Kabwla suggestion that even using the inheritance tree do also matters in performance issue i.e new usage over inheritance tree structure.

What i mean is, in the above test code in place of SomeClass c = new SomeClass() if i had placed Child4 c = new Child4() then the performance of this would be very less even though Child4 is in the inheritance tree plus its method is a virtual method. But run time gets smart in knowing its not a cast to base type as in Base b = new Child4() and hence it directly place a call. But most of developers do not use child class instance directly i.e Child4 c = new Child4() , so i can broadly say virtual inheritance is costly.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s