Skip to content

Preemptive optimisation: do not do it!

Yesterday I wrote about optimisation work flow and in this post I will be discussing why you should not preemptively optimise your program’s source code.  You may wonder what could possibly be wrong with preemptively optimising the source code, it just makes your program faster right?  And that is the trap: while it does make your program faster, if you do not measure the programs performance relative to your performance goals you are effectively taking a shot in the dark with very little real likelihood of hitting your (performance) mark and a real likelihood of unintended consequences in terms of the quality, understandability, complexity and bug count in your program’s source code.

For example, it faster on the CPU you are targeting to compare an integer to zero than to compare an integer to another integer.  Therefore you have decided to write all your loops so they count down to zero instead of the normal approach of counting up from zero.  This will save you a few cycles per iteration of your loop, but have you considered:

  • Counting down and not up in a loop is not conventional in most programming languages and may result in you making math errors which can result in hard to track down bugs in your loop control logic or code inside your loop.
  • Pointer arithmetic in languages like C/C++ is hard enough when counting up (e.g, pObj++) but counting down is even harder to understand as it is so incredibly rarely done and requires extra pointer math to set up.
  • The programmer that comes after you to develop or maintain the source code may not realise you are counting down and not up in your loop and then implement functionality that relies on your loop counting up which would again cause bugs and confusion.
  • That despite your loop being invoked for thousands or millions of iterations, your loop’s control logic is no where near as expensive in terms of CPU operations as function call X that comes right in the middle of your loop which costs millions of cycles by itself every iteration!
  • That it is almost unheard of for loop control logic to be an issue performance wise even when it is in tightest inner loops.
  • That most optimising compilers are perfectly able to make this optimisation for you during compilation on your target platform with none of the above programmer confusion?

My advice here is never optimise without measuring first: as at best you will save a few CPU cycles where it really does not matter at the cost of making your source more complex and harder to understand and at worse you will add subtle bugs to your program and make the source code more complex and harder to understand or maintain!  I have lost count now of how many times I’ve tracked subtle bugs in programs down to programmers making preemptive optimisations without first measuring to see if any optimisation is required and if the extra level of complexity introduced by the optimisation is a desirable trade off.

Occasionally there will be an exception to this rule but in general if you are going to optimise something should always measure first and then optimise only if it is nessessary.

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*