A recent comment on Twitter from Tim Barcz started me thinking about alternative proxy frameworks (alternative to Castle Dynamic Proxy that is). Recently LinFu Dynamic Proxy started gaining some popularity, after it was included as one of standard bytecode providers in NHibernate.
To make things clear. I'm a long time user of Castle Dynamic proxy and I may be biased towards it. I also happen to know how to use it, contrary to all the other frameworks, that’s why the following test may not be realizing their full potential. If you spot a non-optimal use of any of the frameworks in the following test, let me know and I’ll update it.
Having said that, I put together a small sample test project, where I generate a one-interceptor proxy for a simple interface with each framework and call a method on this proxy 100,000 times.
The interface is as simple as it can be:
public interface IMyInterface1
string Method1(int i);
Each interceptor looks roughly the same, and it only sets a return value for the method:
internal class SpringInterceptor : AopAlliance.Intercept.IMethodInterceptor
public object Invoke(AopAlliance.Intercept.IMethodInvocation invocation)
//Debug.WriteLine("Hey, I intercepted the call! - Spring");
I tested four frameworks. Castle Dynamic Proxy 2.1 RC1, LinFu Dynamic Proxy 1.01, Spring.NET 1.2, which is a big framework in itself, but it has some pretty powerful proxying capabilities, and Microsoft Unity 1.2 which has now some proxying capabilities as well.
Here’s the result of the test on my 4 year old, 2GHz one-core PC:
The first pass was a warm up, to let the jitter kick in, so the really important stuff, is the second pass.
Castle Dynamic Proxy was the fastest one, which is not really a surprise for me. It’s designed to be fast and lightweight, and also has some pretty powerful capabilities that allow you to customize the proxy type being created so that you don’t waste cycles intercepting methods you don’t want to intercept, or calling interceptors you don’t need called for a particular method. (for an in-depth overview of Castle Dynamic Proxy see my tutorial series).
The second one was Spring.NET which took over 3 times longer. This is however still pretty fast, and considering that it’s a pretty extensible and configurable framework as well, I’m sure in real life scenario you can squeeze very good performance out of it.
Third one, Unity was an order of magnitude slower than Castle. This is not a surprise considering how bloated and over engineered it is. To be fair however, this may as well be due to strong tie between Unity IoC container and proxy framework. The proxy framework does not seem to be operable outside of the container, so the performance hit, may be partially due to some container overhead.
LinFu was two orders of magnitude slower than Castle. This was really surprising. Or at least until I noticed that it gathers a call stack for each and every invocation, and as I mentioned, this can (as clearly visible) be a performance overkill. I looked for a way to turn it off, but it seems there isn’t any. Also the only way of calling the intercepted method is via MethodInfo.Invoke, which is also a lot slower than direct invocation (or invocation via a delegate).
Note that this is an isolated case of a single performance test. I thought it’s the most important one, but it’s just my opinion. I also didn’t talk about capabilities, which should be your major concern when selecting a framework. – Can it support my scenario is the ultimate test. Frankly, the fastest two, are also the most mature and powerful.
You can check the complete code here.
Here’s a screenshot from a profiler showing the LinFu’s proxy call tree. As you can clearly see, the major performance hit (over 90% of the time!) is in StackTrace constructor. It also obtains a MethodInfo dynamically instead of caching it, like other frameworks do, which is an expensive operation as well.
LinFu has been updated and it no longer collects stack trace information: I re-ran the test and you can see the results here.