You can do all the optimisations you want, but at the end of the day your application will spend 99% of its time waiting for I/O, waiting for data to come in from disk, from the database, waiting for messages back from other systems, even getting bored while it waits to retrieve from slow memory.  In most cases the developer can almost forget CPU cycles at all.  Of course, that doesn't mean ignore silly things like tight loops with no Thread.sleep() call, but most people optimize too early, spending more time on optimization than the design of the solution so it is easy to maintain.

Tip: If you are a new developer who can barely program a stick to be a stick, don't consider optimization of the source code at all until after you have finished and are about to get your code reviewed.

A real world example can illustrate this rule further:

Latham was always droning on about the number of CPU cycles certain operations took versus others.  The customer loved the efficiency talk so much that Latham got put in charge of writing the core of our system – an object cache.  After all, he could fluently use the word 'nanosecond' in a sentence.

It was only after Latham left that we realised he had fundamental design problems in the code that rendered his optimisations useless.  Turns out he couldn't design a stick to be a stick so it was like using thinner paint to reduce drag on a tank. According to his design, the code had to do a sequential walk of the keys to delete a single entry from the cache.  When the first cache cleanup happened one hour after system startup, the system blocked for ten minutes and nobody could work out why. All the optimizations in the world won't save you if your design is poor”.

Of course, don't write silly code that loops without sleeping, like in the following example, which will take 100% CPU unless you add an appropriate sleep:

canRun = true;
for (;canRun;)
{
    if (triggerFile.exists( ))
    {
        // process it
        :
    }
}

A small sleep of a quarter of a second is an infinite rest for the CPU:

canRun = true;
for (;canRun;)
{
    if (triggerFile.exists( ))
    {
        // process it
        :
    }
    try{Thread.sleep(250);} catch {InterruptedException e};
}

Exception: The few developers who write library code that dozens will be using should consider performance a lot, remembering that good performance will come from the design just as much as the code.

Optimisation in this situation should only be done once all the parts of the complete solution are clear or when there are clear performance problems that affect others.

Tip: Salespeople from organisation X come to sell you a solution that everyone is using to solve their performance problems.  It's a no-brainer right?  Just install this tool and you save half a second on every page request. But consider, do you even have a performance problem?  Are customers upset about performance enough to warrant the additional complexity it will add? You are probably better off using the time and money to build new features the customer wants.

blog comments powered by Disqus