Software optimization
Optimization of software is making it use less resources to do the same thing. Some resources that are typically targeted for optimization are the amount of memory used while executing, time required to execute and the amount of disk space or other storage required to execute. Optimization is related to refactoring (which is making software do the same thing more readably and maintainably), as in many cases the simplified code allows for shorter and quicker solutions which demand less resources.
Less frequent aims of optimizations are the time required by the software team to design, write and test the software and the time, memory or disk space required to compile the software. It is not unusual for reducing the use of one of these resources to cause another resource's usage to increase. Weighing the pros and cons of different optimizations is important.
Optimization is something that can be performed in all facets of the programming effort, from design to runtime usage. Programmers can implement certain optimizations at the time of the project's design and writing; they may use automatic optimization features of tools used for building the project, like compilers; and they may analyze their code using specialized tools like profilers and debuggers after it was written in order to improve existing code.
It's a very large topic; some optimization techniques follow, each big enough to deserve its own Wikipedia article:
- don't optimize if you can help it!
- profiling to find critical parts of the software (and then optimizing those)
- measuring attempted optimizations to see if they actually improved matters
- using a better algorithm or data structure to reduce time, space, or both
- rewriting code in a lower-level language (C or assembly language are common choices) to reduce both time and space
- precomputation, memoization, caching, and hints to reduce time
- using packed bit-fields or packed bytes to reduce memory usage
- alignment
- using data instead of code to reduce memory usage
- using overlays or virtual memory to reduce memory usage
- using a compiler, or a better compiler, on your code, or supplying different optimization flags to your compiler
- parallellization
- specialized fast-path code to handle common cases
- normalization or denormalization of data
- reorganization of data to reduce false sharing, improve packing, improve locality of reference (by rearranging fields in a record or by moving some fields to other records.)
- lazy evaluation
- speculation and prefetching
- reduction of overhead by batching
The compiler optimization page lists a variety of techniques which are usually employed by compilers. Some of these techniques are too difficult for humans to employ directly.
General issues
Need for optimization
Often, programmers begin to optimize all of their code at the design stage, or wherever they see fit afterwards. While performance is a crucial aspect of software engineering, optimizations made too early may severely impact the designed system's other aspects, such as portability or expandability. As a general rule, optimizations make the code more difficult to understand, and hence to maintain. Therefore, optimization is a process that needs to be started with a clear idea of what and how to optimize.
A very important thing to understand is the fact that bottlenecks have the greatest influence on software performance, and not most other pieces of code. Thus, when John Carmack was developing Quake, he noted the gameplay was extremely slow. Using a profiler, he discovered that the built-in scripting language, QuakeC was being interpreted too slowly to match game speed. He then re-wrote the QuakeC execution code using a technique called Just In Time (JIT) instead. This immediately solved all of the performance problems in a way which would not be possible if he optimized e.g. the graphical engine (doing which would also be much more difficult).
References: