When is optimisation premature?

2018-12-31 04:18发布

As Knuth said,

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

This is something which often comes up in Stack Overflow answers to questions like "which is the most efficient loop mechanism", "SQL optimisation techniques?" (and so on). The standard answer to these optimisation-tips questions is to profile your code and see if it's a problem first, and if it's not, then therefore your new technique is unneeded.

My question is, if a particular technique is different but not particularly obscure or obfuscated, can that really be considered a premature optimisation?

Here's a related article by Randall Hyde called The Fallacy of Premature Optimization.

20条回答
听够珍惜
2楼-- · 2018-12-31 04:22

The point of the maxim is that, typically, optimization is convoluted and complex. And typically, you the architect/designer/programmer/maintainer need clear and concise code in order to understand what is going on.

If a particular optimization is clear and concise, feel free to experiment with it (but do go back and check whether that optimization is effective). The point is to keep the code clear and concise throughout the development process, until the benefits of performance outweigh the induced costs of writing and maintaining the optimizations.

查看更多
低头抚发
3楼-- · 2018-12-31 04:22

I try to only optimise when a performance issue is confirmed.

My definition of premature optimisation is 'effort wasted on code that is not known to be a performance problem.' There is most definitely a time and place for optimisation. However, the trick is to spend the extra cost only where it counts to the performance of the application and where the additional cost outweighs the performance hit.

When writing code (or a DB query) I strive to write 'efficient' code (i.e. code that performs its intended function, quickly and completely with simplest logic reasonable.) Note that 'efficient' code is not necessarily the same as 'optimised' code. Optimisations often introduce additional complexity into code which increases both the development and maintenance cost of that code.

My advice: Try to only pay the cost of optimisation when you can quantify the benefit.

查看更多
忆尘夕之涩
4楼-- · 2018-12-31 04:25

My question is, if a particular technique is different but not particularly obscure or obfuscated, can that really be considered a premature optimisation?

Um... So you have two techniques ready at hand, identical in cost (same effort to use, read, modify) and one is more efficient. No, using the more efficient one would not, in that case, be premature.

Interrupting your code-writing to look for alternatives to common programming constructs / library routines on the off-chance that there's a more efficient version hanging around somewhere even though for all you know the relative speed of what you're writing will never actually matter... That's premature.

查看更多
只若初见
5楼-- · 2018-12-31 04:27

Optimization can happen at different levels of granularity, from very high-level to very low-level:

  1. Start with a good architecture, loose coupling, modularity, etc.

  2. Choose the right data structures and algorithms for the problem.

  3. Optimize for memory, trying to fit more code/data in the cache. The memory subsystem is 10 to 100 times slower than the CPU, and if your data gets paged to disk, it's 1000 to 10,000 times slower. Being cautious about memory consumption is more likely to provide major gains than optimizing individual instructions.

  4. Within each function, make appropriate use of flow-control statements. (Move immutable expressions outside of the loop body. Put the most common value first in a switch/case, etc.)

  5. Within each statement, use the most efficient expressions yielding the correct result. (Multiply vs. shift, etc)

Nit-picking about whether to use a divide expression or a shift expression isn't necessarily premature optimization. It's only premature if you do so without first optimizing the architecture, data structures, algorithms, memory footprint, and flow-control.

And of course, any optimization is premature if you don't define a goal performance threshold.

In most cases, either:

A) You can reach the goal performance threshold by performing high-level optimizations, so it's not necessary to fiddle with the expressions.

or

B) Even after performing all possible optimizations, you won't meet your goal performance threshold, and the low-level optimizations don't make enough difference in performance to justify the loss of readability.

In my experience, most optimization problems can be solved at either the architecture/design or data-structure/algorithm level. Optimizing for memory footprint is often (though not always) called for. But it's rarely necessary to optimize the flow control & expression logic. And in those cases where it actually is necessary, it's rarely sufficient.

查看更多
与君花间醉酒
6楼-- · 2018-12-31 04:30

If you haven't profiled, it's premature.

查看更多
柔情千种
7楼-- · 2018-12-31 04:30

The need to use a profiler should be left for extreme cases. The engineers of the project should be aware of where performance bottlenecks are.

I think "premature optimisation" is incredibly subjective.

If I am writing some code and I know that I should be using a Hashtable then I will do that. I won't implement it in some flawed way and then wait for the bug report to arrive a month or a year later when somebody is having a problem with it.

Redesign is more costly than optimising a design in obvious ways from the start.

Obviously some small things will be missed the first time around but these are rarely key design decisions.

Therefore: NOT optimising a design is IMO a code smell in and of itself.

查看更多
登录 后发表回答