Sunday, September 18, 2011

Performance comparison of .NET method calls

In this post I will try to compare performance of various method call types in .NET including IL's call, virtual call, reflection method call, delegates, compiled lambda expressions and Action/Func.

It is not too rare for me to pick up and say something about the internals of .NET framework or just general Microsoft stack only later to realise I was wrong - not in this case because I was wrong although that happens too but because things have changed since I last checked up or read upon them. This happens a lot on Stackoverflow where it is even more crucial to be right - don't wanna give false information to others.

With the advent of lambda expressions and introduction of generic delegates aka Action<T>, Func<T>, etc in .NET 3.0 things have certainly got funkier - pun intended! Now in .NET 4.0, we have the dynamic stuff which is even better, certainly solving many difficult problems we were facing in a statically typed environment. Best example is Simple.Data which I just love for its simplicity and would be impossible without it.

Now this is all well and good but it does come with a price tag - performance hit here - which we all know exists but its kinda like banking direct debit, you know you have set it up and it goes out of your pocket but since you do not see a bill, you do not realise how much you are paying. On the other hand, sometimes you might drop off the other end of spectrum and start micro-optimising by not using any reflection or dynamic hence loose the opportunity to make your code more maintainable by not using more expensive but much more elegant approach which involves dynamic or lambda expressions.

I remember from the old VB6 days when we were talking about late binding and how evil they were and we were to avoid them like plague. Now 10-12 years later and things have changed a lot: we are trying to solve much more complex problems and we need new tools and new languages hence the popularity of functional languages. On the other hand, our hardware have got noticeably better so what would be deemed to be a no-no back then, it has become commonplace to use. But I certainly see a new wave of awareness to the performance, thanks to the popularity of mobile and tablet platforms where memory and CPU just cannot be taken for granted.

Anyway, from whatever angle you look at it, it is useful to have a comparison.

I have created different scenarios where the same piece of code (which does a simple calculation) is called in a various ways. Here

As can be seen, calling DynamicInvoke on a delegate has the worst performance. Of notice, is relatively good performance of Dynamic objects compared to reflection.

In the next post we will discuss the detail and code for the test.

No comments: