This is the first article in our four-part series talking about performance problems in software products.
Product design or high-level code?
The majority of performance problems are introduced at the highest layers of abstraction and in the design itself. Why does it seem to occur most often in the highest layers? Well, at higher levels of abstraction, there is less code which actually induces more work as it can take just a simple mistake to produce a large catastrophe in the program. And product design? Many designs produce more work or they don’t use parallelism. Even optimization to make the algorithm quicker will not help: the algorithm will have to be changed.
Designing for performance is a controversial area: some think you must always start by designing for performances, while others think that you should start with something that works and optimize later. Both of these approaches have merit but the correct balance must be found for intended performance. The high-level design *must* be done with performance in mind, because later on down the road, these poor high-design decisions will be impossible to change. When creating the high-level design, the process should be done with less work instead of quicker work that may have unintended consequences at a later time. Also think about parallelism: many classical algorithms do not take parallelism into account and instead they focus mainly on efficiency. The lower layer changes should be first implemented with something easy to understand and maintain and then it should be optimized only if it is needed.
The other important aspect of design for performance is to understand the environment of the system, product, module, and sub-module. Is the CPU the major environment impacting performance? How about cache, disk or other options?
Also, certain algorithms perform reasonably fast when specific conditions are met. For example, an algorithm might assume that a number of files is much less than the number of folders. These assumptions must be logged and if the conditions are not met, an error should be reported. A warning or error is a better solution in determining the source of a problem than a mysterious slowdown of an unknown cause.
It is important to experiment before making any decision regarding performance design: having realistic benchmarks to support these decisions is perfect but, in many cases, a small test program will be adequate to correctly perform the work.