When Is Optimization Premature

When is optimisation premature?

Don Knuth started the literate programming movement because he believed that the most important function of computer code is to communicate the programmer's intent to a human reader. Any coding practice that makes your code harder to understand in the name of performance is a premature optimization.

Certain idioms that were introduced in the name of optimization have become so popular that everyone understands them and they have become expected, not premature. Examples include

  • Using pointer arithmetic instead of array notation in C, including the use of such idioms as

    for (p = q; p < lim; p++)
  • Rebinding global variables to local variables in Lua, as in

    local table, io, string, math
    = table, io, string, math

Beyond such idioms, take shortcuts at your peril.

All optimization is premature unless

  • A program is too slow (many people forget this part).

  • You have a measurement (profile or similar) showing that the optimization could improve things.

(It's also permissible to optimize for memory.)

Direct answer to question:

  • If your "different" technique makes the program harder to understand, then it's a premature optimization.

EDIT: In response to comments, using quicksort instead of a simpler algorithm like insertion sort is another example of an idiom that everyone understands and expects. (Although if you write your own sort routine instead of using the library sort routine, one hopes you have a very good reason.)

Is premature optimization really the root of all evil?

It's important to keep in mind the full quote (see below):

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.

Yet we should not pass up our opportunities in that critical 3%.

What this means is that, in the absence of measured performance issues you shouldn't optimize because you think you will get a performance gain. There are obvious optimizations (like not doing string concatenation inside a tight loop) but anything that isn't a trivially clear optimization should be avoided until it can be measured.

The biggest problems with "premature optimization" are that it can introduce unexpected bugs and can be a huge time waster.


Sample Image

There is no doubt that the grail of efficiency leads to abuse. Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.

Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified. It is often a mistake to make a priori judgements about what parts of a program are really critical, since the universal experience of programmers who have been using measurement tools has been that their intuitive guesses fail. After working with such tools for seven years, I've become convinced that all compilers written from now on should be designed to provide all programmers with feedback indicating what parts of their programs are costing the most; indeed, this feedback should be supplied automatically unless it has been specifically turned off.

Premature optimization and Premature pessimization related to C++ coding standards

What he means by premature pessimisation, I think, is just the opposite of premature optimisation: a fundamental disregard of which data structures and algorithms to use.

Premature optimisation is often concerned with minute details of algorithms that can well be tweaked later and don’t need to be paid attention to at the beginning.

Premature pessimisation, by contrast, concerns the high-level design of code architecture: a fundamentally inefficient interface for your library for instance cannot be fixed later by optimising, since the public interface is pretty much cast in stone.

Practical rules for premature optimization

What is premature optimization?

Premature optimization is the process of optimizing your code (usually for performance) before you know whether or not it is worthwhile to do so. An example of premature optimization is optimizing the code before you have profiled it to find out where the performance bottleneck is. An even more extreme example of premature optimization is optimizing before you have run your program and established that it is running too slowly.

Are we at the point now where deciding between an O(n^n) and O(n!) complexity algorithm is irrelevant? What about O(n) vs O(n*n)?

It depends on the size of n and how often your code will get called.

If n is always less than 5 then the asymptotic performance is irrelevant. In this case the size of the constants will matter more. A simple O(n * n) algorithm could beat a more complicated O(n log n) algorithm for small n. Or the measurable difference could be so small that it doesn't matter.

I still think that there are too many people that spend time optimizing the 90% of code that doesn't matter instead of the 10% that does. No-one cares if some code takes 10ms instead of 1ms if that code is hardly ever called. There are times when just doing something simple that works and moving on is a good choice, even though you know that the algorithmic complexity is not optimal.

Every hour you spend optimizing rarely called code is one hour less that you can spend on adding features people actually want.

Am I understanding premature optimization correctly?

This is the right strategy in general. Get the code to work, thoroughly covered with automated tests.

You can then run the automated tests while the program is under control of a profiler, to find out where the program is spending time and/or memory. That will show you where to optimize.

And it will be showing you how to optimize working code, not code that may or not work when it's all put together.

You don't want code that fails optimally.


The quote I was failing to remember is from Mich Ravera:

If it doesn't work, it doesn't matter how fast it doesn't work.

Is it a premature optimization to use std::move()?

The other answers focus too much on the technical aspects of the question for my taste, so I will try to give a more general answer.

In short: No, using a "trick" like std::move in the way it's described in the question isn't a premature optimization. Not using std::move when it can be used is fine too, unless the code is already known to be performance critical.

The need to avoid premature optimization is sometimes understood as "don't optimize, until you can prove it's necessary", but I prefer to read it as: "don't waste time solving problems unless you know they need to be solved".

Premature optimizations require spending effort in order to optimize what may not need to be optimized, and usually transform a simple problem into a complex problem while doing so. From that perspective, I would classify any long pondering of the question itself as premature optimization.

A related example: People working in performance critical code will often pass arguments as const references ( const std::string& ). Because that's what they are used to do, they will use the same pattern in code that isn't performance critical, even though they could just use pass-by-copy ( const std::string, or even std::string ). That isn't a premature optimization either.

Planning for efficiency early vs Premature optimization

What I usually do is to apply those optimzations that don't cost me anything (or almost nothing). I also stay on the lookout for algorithms that don't scale well and are called very often. Other than that, I do not optimize until the software runs and I get a chance to fire up the profiler. Only then I will invest some serious time into optimization.

Can early testing lead to premature optimization?

Optimizing prematurely probably means that you should fix design and/or coding 'issues' at an early stage. If you wait with this, more code will be added and it will be more complicated (and at least time consuming) to improve those issues.

The result is that you - as positive side effects - reduce the number of bugs, not only by optimizing but also later.

You know when you are optimizing prematurely when you improve the structure (either code or design), without changing functionality. For this regression testing can be used:

Run tests, all should be ok
Improve code/design
Run tests, all should be ok

Of course this only works when you have very good regression tests.

If you mean performance optimmizing, this is completely different and I would advice not to do any performance optimizing unless you run into problems performance wise, or when you know beforehand performance might be an issue. And if the last case is true, it should be part of the design.

Is premature optimization in SQL as evil as it is in procedural programming languages?

I would say that some general notions about performance are a must-have : it'll prevent you from writing really bad queries that can hurt your application (Even if you don't have millions of rows in your tables).

It'll also help you design your database so it's more officient-oriented : you'll have some ideas about where to put indexes, for instance.

But you shouldn't have performance as a first goal : the first thing is to have an application that works ; and, then, if needed, you'll optimize it (having some performance notions while developping will help you have an application that's easier to optimize, though).

Note I would not say that "having notions about performances" is "premature optimization", as long as you don't just "optimize", but just "write correctly" ; I would rather call it good practice that'll help to write better quality code ;-)



Related Topics



Leave a reply



Submit