I’ve just spent the last couple of days trying to optimise the code used by our HTTP Handlers. One of the things we want to do is use an ADN (which stands for Active Delivery Network I think.). This is something that Akamai and other content delivery networks use to help speed up a site. Basically an ADN is a cache on the web. Requests to your site go through the ADN first and if it can handle that request the requester gets the content quicker.
However, I don’t want to rely soley on the ADN. What I would like is for our code to be as fast as it can. It sounds obvious but sometimes the obvious things get overlooked. We don’t get to concentrate writing fast optimised code because of scope creep and all the little add-ons that get thrown in. Some of these are needed for the business.
I had written a component a while ago, and I used TDD to develop it and felt quite pleased with myself. The code looked clean and appeared to run well. I ran performance tests against it (we use a Python tool called pylot to do this) and again it seemed to stand up well.
Now, with the current re-working of the code and splitting things out into separate pieces I thought it a good idea to go back and test each handler by itself, to see how it stood up to 300 requests per second. My bit of code that I was so proud off behaved shockingly. It gobbled up memory, CPU usage was crazy.
How to improve this? Was there an issue with Dependency Injection? Shouldn’t be. If a new object needs to be created, then does it matter whether it is passed into a constructor or done within a method. From a testing prespective using Dependency Injection is better. Was there an issue with lots of classes? I better clarify that, instead of using one large class, I’m using six smaller classes. Again, should there be a problem? Not that I could immediately think off.
In order to solve the problem I went to the code and started commenting out chunks, hard-coding certain calls, so that I could test the process piece by piece. One of the nice things about breaking the code into smaller classes was the ease with which this could be done. I eventually found the problem to be with one of the smaller helper classes. As I’ve mentioned in a previous post, I had a big problem and broke it down into smaller chunks until I isolated the problem. In this exact case the issue was with a legacy object that does GEOIp lookup. When that object was being created it loaded up a DAT file. It was this that was causing the problems with memory.
Right now I’ve moved the object into the only function that uses it, and this helper class is a wrapper between my component and the older legacy stuff. When I come to running performance tests against this function I’ll see what happens with memory usage then.
I hope this makes sense. I’ll post this article now, but come back in a few days to proof-read it and see if it’s coherent. Right now I wanted to get my thoughts down.