12 Avoid optimizations and generality

 

This chapter covers

  • Minimizing generality to reduce coupling
  • Thinking of optimization in terms of invariants
  • Managing the fragility from optimizations

Performance optimization and generality are two games programmers play that often hurt more than they help. When we say optimization in this chapter, we mean performance optimization, which involves increasing the throughput of code or reducing its duration. By generality, we mean the code encompasses more functionality, usually through more general parameters. To illustrate what we mean by generality and how it can be harmful, consider the following example.

If someone asks you for a knife, handing them a Swiss Army knife might be a godsend if the recipient is in a survival situation. However, imagine if the recipient is a chef in a professional kitchen; a paring knife might be more welcome. In this parable, as in code, the design accommodating the generality may be more burdensome than the generality is helpful. When it comes to generality, the context is everything.

In this chapter, we begin by exploring how these practices are often harmful. We then take a deep dive into generality and optimization, discussing when to do each and when not to.

12.1 Striving for simplicity

12.2 When and how to generalize

12.2.1 Building minimally to avoid generality

12.2.2 Unifying things of similar stability

12.2.3 Eliminating unnecessary generality

12.3 When and how to optimize

12.3.1 Refactoring before optimizing

12.3.2 Optimizing according to the theory of constraints

12.3.3 Guiding optimization with metrics

12.3.4 Choosing good algorithms and data structures

12.3.5 Using caching

12.3.6 Isolating optimized code

Summary