Software architecture training : our two day "From Developer to Architect" training course is an interactive introduction to software architecture and aimed at software developers moving towards their first software architect role. Now available throughout Europe. Read more...

Premature Optimisation

I'd like to talk to you about a sensitive subject that has been affecting me and, I suspect, affecting many of you as well. It's embarrassing so I'll say it first and you can all nod in agreement.
"We're having problems on my project with being premature - premature optimisations"

Did you all look about the room and then give a little sigh of understanding?

The projects I've worked on (most I've been involved with are in investment banking) have strict performance requirements. In my case it tends to be about latency (you don't want to buy/sell a fraction too late) but you may have different ones such as throughput, network volumes, storage etc which are just as important to your system.

From an architecture point of view there are some sensible decisions you can make to help achieve your SLAs - how your components communicate, where components are located, what needs to be guaranteed, what form messages take, where transactions are required etc. However, time and time again I've seen that you can't accurately predict where the bottlenecks in the code will be. This is partly due to the usage and input data being an unknown but also that complex systems tend to interact in complex ways.

The only way to really know where the problem areas are is to exercise the system with sufficient instrumentation to track them down. Often you'll find that the biggest problems are structural - maybe you've partitioned your data or services in an incorrect way and a small part of your system is thrashed but the rest is idle. Correcting these high-level problems will yield massive benefits. Once they're solved you can look inside the components (follow the data flow) for the code level bottlenecks with tools such as jprofiler. Normally I'm surprised at exactly where the problems are but I shouldn't be as no one writes code you expect to be slow! You can now tweak the code.

I've gone off on a tangent but tweaking the code for reasons of performance is actually the last stage of performance enhancement. However you'd never guess that by looking at some of the code I've come across.

For example the Java 1.5 concurrency utilities have actually made this problem worse. The utilities themselves are excellent and allow for much more performant code *when used correctly* but I've seen some horrendous, spaghetti locking code where previously someone would have just used a synchronize. When I've queried it the developer spent a lot of effort and has no proof it's better or required.

Some guidelines for your developers (please send in your own too!)

  • Get the structure/architecture of the system correct before you worry about code performance
  • Profile your systems performance through the development process. It's much easier to add tests and instrumentation as you go rather than retrofit.
  • Instrument at logical system boundaries e.g. latency/throughput for a request-response service. Don't start by attaching a java profiler to a JVM and looking at methods.
  • Write code in the simplest way that is efficient. For example choose a hashmap over a list if you are searching by keys - it's more efficient but not more complex.
  • Don't write more complex code for performance reasons *unless* you have metrics to prove it is necessary. You should measure before and after the change and if the more complex code does not give a significant benefit then remove it.
  • Be pragmatic. If the cost of changing the software to make it faster (both development and maintenance/support) is more expensive than more hardware, are you sure it's the right decision?

Keep it simple, measure and make sensible modifications.



Re: Premature Optimisation

It's funny, in my experience, developers tend to optimise too much. Architects too little... Developers will agonise over whether to use a String or a StringBuffer to save a few milliseconds. Meanwhile the Architect will stick the database on a server in Venezuela...

Ok, I exaggerate, but I think as System Architects we are often guilty of leaving Non-Functionals to the end and then hoping for the best. The trouble is, clients always want to pay for the functionals and assume that 'good practice' will somehow magically take care of the non-functionals for free...

Tom

Re: Premature Optimisation

I think I'm with Tom on this - "optimisation" can be a moot point before you've even written a line of code!

"Tardy" optimisation is just as big a problem. The key, as you suggest, is probably to test early and test often to ensure you're neither too early or too late with your optimisation. And not to restrict your testing and optimisation to the build phase.

Re: Premature Optimisation

Leaving non-functionals until the end of the project ... right ... this is why I'm keen on RUP style "executable reference architectures" that prove the key non-functionals as soon as possible. And it's also the same reason why I believe even "agile" projects need some form of architecture/architectural spike. I've been burnt by non-functional requirements before. ;-)

Add a comment Send a TrackBack