One should only write optimized code?
No, one should not write only optimized code. One should write maintainable and readable code, which adheres to the KISS principle. Depending on the foreseeable scenario, certain optimizations could be introduced in order to meet the performance requirements.
The dangers of early optimization “fever” are
- loosing yourself in the details instead of keeping an eye on the big picture.
- to invest a lot of time and effort in code snippets which are not that crucial for perceived and actual performance.
- the loss of flexibility with regard to changing usage scenarios and requirements.
- the loss of platform independence (processor, instruction set, HW peripheral)
- tight coupling on either hardware or between software modules.
Suppose a “well-written” program does not meet the performance criteria, there are a couple of things to check.
- Identify the performance bottleneck: is it the algorithm or the implementation?
- Identify the functions, the time it takes to run the functions, and how many times these functions are called within the scenario under scrutiny.
- What is the influence of other software threads running?
Select the right algorithms
Sometimes, an alternate algorithm is more suitable depending on the amount of data, or the type and ordering of data which is presented for processing. One algorithm might be more suited for less data, which is totally unsorted, but another one is able to do much better with large sets of almost sorted data. No need to reinvent the wheel. If the interface is cleanly defined, it should be quite easy to swap-in the other algorithm.
Know your lookup strategies
Software “works” with data: it needs to search into it, iterate over it, perform calculations on it. The matter of access to data is important. Is it random access, keyed to an index, or sequential? Hashes, binary trees, double-linked lists, single-linked lists, arrays, etc… all have their uses and have optimal efficiency scenarios. Make sure you pick the right one for the right situation!
When to copy data
Control over when and why (with regard to memory allocation) maybe adds complexity, but it is an important factor in the performance aspect. Allocation and deallocation are usually expensive operations. Data object parameter passing by reference should be the rule, not the exception.
Which part of the code is the most interesting to optimize?
Good candidates are the function(s) which take the most aggregated processing (computing + IO) time. Hence, it is important to know how long the function call takes, and what the (minimum, average and maximum) duration of a single execute is. Also, one needs to consider the call hierarchy. Fortunately, there are good tools which do this, and which can suggest the primary targets for (code) optimization.
It is the other ones fault
Often forgotten, is the influence of other tasks and threads on the algorithm. System cache poisoning as a result of context switching, or because of semaphores (cascading to memory fences, resulting in cache flushes) can have a tremendous influence on timing and throughput performance. Even well-balanced software (under execution unit monopoly conditions) can fail miserably whenever more load from other tasks is introduced to the system. Under these conditions, a sub-optimal solution (when compared to the processing monopoly solution) causing less context switching could deliver. The usage scenario is everything and it is virtually impossible to take it all into account beforehand(, but a good developer tries to foresee as much as possible):
“Tweaking and optimization” is a natural phase in every software development.
Speak Your Mind