Implications of Proxy classes

I said in a previous post about there being some things to watch out for when using proxies…  Here’s what I’ve seen, there’s probably more, add your experiences to the comments 🙂

This is really only an issue if you violate the Liskov Substitution Principle (LSP), but it’s worth knowing as it can catch you out.  Have a look at this test:

var containerWithAspect = new WindsorContainer();
containerWithAspect.AddFacility("aspectFacility", new AspectFacility(new TestAspectSelector()));
containerWithAspect.AddComponent<ITestService, TestServiceImpl>();
 
var containerWithoutAspect = new WindsorContainer();
containerWithoutAspect.AddComponent<ITestService, TestServiceImpl>();
 
Assert.IsFalse(containerWithAspect.Resolve<ITestService>() is TestServiceImpl);
Assert.IsTrue(containerWithoutAspect.Resolve<ITestService>() is TestServiceImpl);

As you can see, when we’re applying an aspect the instance we get out of the container is not a TestServiceImpl, it’s a proxy class…  The proxy class (which is dynamically generated) implements the service interface (ITestService) and aggregates the implementation (TestServiceImpl).  It then forwards on the calls to the implementation.  As I said, it’s normally a bad smell to do what I’m doing in this test, but it’s good to be aware of.

Note:  If you want to get hold of the real thing, the proxy class also implements IProxyTargetAccessor which you can then use to get at the real thing…  However, I’d suggest if you’re doing this they’d better be a good reason!

Another thing to consider is performance…  Here’s a test to highlight the performance impact:

Here are the results (doesn’t really matter what box I ran these tests on – I just want to highlight the difference).

Action With (ms) Without (ms) With (ticks) Without (ticks)
First resolve 247 0 886,338 46
10,000 resolutions 578 126 2,070,956 452,891
10,000 method calls 48 0 173,303 369

The first resolve is much slower because that’s when we IL emit the class which is our proxy (I’m guess I’ve not looked at the code).  This is only ever done once for the lifetime of the process so think of it just like ASP.Net complication…  If you want your first call to be quick, make sure you resolve it before you make your real call…

10,000 resolutions takes about 452ms slower 0.0452 ms per call slower…

10,000 method calls takes 48ms, which works out at 0.0048ms per call…  To compare this to a normal method call we need to use the ticks (because as you can see calling a method is pretty darn quick!).  The difference is massive as you can see.

So is this performance impact important?  It depends.  For me, no.  The difference pails into insignificance when you consider what the implementations are actually doing.  The application I’m building is multi tiered, it eventually sticks something in or gets something out of a database in response to someone calling a web service. I have no idea on average how many resolutions / method invocations there are before I get to the point where my data is ready to be stuffed across the wire to a web service, across the network again to a database server, then into the database, all in a transaction which needs committing….  I’m pretty confident that, as a percentage, the overhead of the aspect is insignificant.  However, if this was in a sort algorithm then I’d be nuts to use an aspect due to the performance – but I’d be nuts anyway!

It’s worth being aware of the fact that AOP has a performance impact.  People can use it as an argument not to use it.  But, remember your context…  A method call is VERY quick.  A method call with a proxy in the way is comparatively MUCH slower.  But, how much slower in the context of the entire operation?  Context is king.

Lastly…  One thing you may notice is a fun stack trace when debugging.  You’ll get an extra couple of items in the stack for each intercepted method call, which can make reading the stack trace in the debugger a bit more difficult.  Also, when you hit F11 to step in you’ll disappear off into Windsor…  However, if you’re following TDD then, when you do crack out the debugger (many practitioners argue that it’s rare if not bad) aspects won’t be applied (you’re testing one thing at a time remember).  If you’re debugging an integration test then you can turn off aspects to get a cleaner stack (if it’s really that intrusive).  So in the grand scheme of things I don’t think this is a massive issue.

Advertisements

About Tom Peplow

C# .Net developer based in London and the South Coast
This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

2 Responses to Implications of Proxy classes

  1. Pingback: Aspect Oriented Programming with Castle Windsor | pep => lowdown

  2. Pingback: Logging Aspect | pep => lowdown

Leave a Reply

Fill in your details below or click an icon to log in:

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