Jason Baker
Jason Baker

Reputation: 198867

Planning for efficiency early vs Premature optimization

I seem to notice two schools of thought emerging in regards to optimization:

  1. Premature optimization is the root of all evil. You should only optimize when you've written the most readable and simplest thing possible. If after profiling you determine that the software is too slow, you should optimize.
  2. Optimizations should be done early in a project's lifecycle. Optimizations need to be planned for, but should be done reasonably.

On the face of things, they seem to be fairly opposed viewpoints. The thing is, I see the merit in both schools of thought. I can also think of times when both of these ways of thinking have helped me write better and faster software.

Is there any way to reconcile these two ideas? Is there a middle ground? Is there a time when one idea is the best tool for the job? Or am I presenting a false dichotomy and both views can co-exist peacefully?

Upvotes: 13

Views: 1989

Answers (15)

David
David

Reputation: 359

This question is as relevant in 2025 as it was in 2009.

  1. The first question you should ask is this: what are my constraints?
  2. The second question is: given these constraints, what performance characteristics do I need?
  3. The third question is: do I need additional optimization beyond the simplest implementation to meet these performance characteristics?

Premature optimization is the root of all evil mainly refers to skipping one or more of these steps, and proceeding to optimize anyway.

Optimizations should be done early in a project's lifecycle mainly refers to optimizing early based upon known constraints and performance characteristics.

Both philosophies can lead one to making the wrong decisions early on, which creates additional work down the road. Following either in isolation may lead you to make either more type 1 errors or type 2 errors than you need to: https://en.wikipedia.org/wiki/Type_I_and_type_II_errors

Ask those 3 questions early to help make the right decisions. Sometimes, you just don't know what you need early on and need to assess as the project moves forward, in which case it may be worthwhile to create a simple prototype/proof-of-concept. That gives you a chance to assess bottlenecks, then re-write a fuller implementation with those bottlenecks in mind. Done well, this just means you're spending the time you need in order to answer these questions, ultimately saving you additional time and headaches in the long run.

Upvotes: 0

Skizz
Skizz

Reputation: 71130

I would also have: Use appropriate and efficient data structures from the start. This does cover a wide range of things:

  1. Know how all the standard containers work, what they're good at and what they're bad at. eg. SortedDictionary is quick at insertion and searching but poor at deletion. LinkedList is quick to add and delete but poor at searching and so on.
  2. Know where your bottle necks will be. Will it be cpu, disk, memory, graphics, IO, networking, etc. Know how to utilise each one efficiently, each area requires different design patterns. This really depends on the application being developed as well - what is the core metric to concentrate on, for UI responsiveness, for data processing good disk caching.
  3. Multhreading. If the application will scale to multiple cores it needs to be decided upon very early on in the development life cycle if such a system is needed. Bolting threading on at a later stage is much more costly.

Some of the answers you will know from experience, some will require research, but it will never be guess work.

Upvotes: 2

Alex Fort
Alex Fort

Reputation: 18819

I would say the middle ground would be to keep known inefficiencies in mind when you're writing code, but don't optimize early if it would mean extra time in initial development, or added complexity.

My theory is, "Write simple working code, then optimize as testing requires."

Upvotes: 1

user414441
user414441

Reputation:

The code , besides providing providing the basic functioanlity, has three more feature that software developer need to provide:

  1. Performance
  2. Maintainability
  3. Robustness

An idle code would provide all three of these. with limited resources, the call of which portion of code should be optimized for what needs to be evaluated. Optimization of one of these, at the cost of others, is dangerous, and should be avoided as far as possible.

Upvotes: 1

Jas Panesar
Jas Panesar

Reputation: 6639

Build it as well as you can the first time without adding lots of time or effort. Then let it fight for your attention.

Upvotes: 2

Syntax
Syntax

Reputation: 1314

This is where planning comes into play. If you have a great plan and have a good model for what you're writing, optimization should only have to occur in post. If you find yourself needing to optimize a lot of your code you are most likely doing something incorrectly to start with.

A lot of this will also come with experience and working on similar tasks. Generally the only time you should have to write something that needs to be optimized is when you are covering things you've never worked with prior. Optimizations happen in the planning phase and in the post project phase IMO.

Upvotes: 1

ephemient
ephemient

Reputation: 205034

Adapting the quote "it's tactics if you win and it's cheating if you lose", I'd say

It's "planning for efficiency" if it worked and it's "premature optimization" if it didn't.

Upvotes: 3

HLGEM
HLGEM

Reputation: 96648

Databases in particular are not easy to refactor and are often the largest bottleneck in the system due to designers who think they shouldn't care about performance when they design. This is short-sighted. There are many known database optimizations that will almost all of the time be faster. To not use them in your design and intial coding to avoid "premature optimization" is silly. For instance a cursor will almost never (unless you are looking for running totals) perform better than a set-based query in SQl Server. To write a cursor instead of a set-based query is not faster (once you understand set-based queries), so there is no reason to start with cursor based code. Same thing with derived tables vice subqueries. Why write code you know 90% of the time will be slower than other code which takes the same amount of time to write?

Choosing to use a tool that makes it hard later to performance tune is also a short-sighted decision, so in considering how you intend to access the database, this should be part of what you consider.

Anyone who codes against a database or who designs them, should take the time to read up on performance tuning for their particualr type of database. Knowing in advance how to write a sargeable query and what sort of things should have the indexes you you start with and what are the usual kinds of bottlenecks will help you do the job better the first time.

Upvotes: 1

sblundy
sblundy

Reputation: 61434

I like this guy's formulation.

  1. Optimization by using a more sensible overall approach.
  2. Optimization by making the code less weird.
  3. Optimization by making the code more weird.

The first two are you point 2. His 3 is your 1 and the one that is the root of all evil. And he's right, optimizations that make code "more weird" make it more complicated and more difficult to understand, resulting in more bugs and maintenance headaches.

Upvotes: 2

David Thornley
David Thornley

Reputation: 57076

The ideal is to profile first, then optimize where necessary, but that doesn't work with design; by the time you've got anything executable to profile, changing the design would be very expensive. Therefore, the design has to pay attention to efficiency up front. Usually this means sketching out efficient algorithms up front, and keeping enough flexibility to change later. (This is often best done with good separation of function, keeping modules as independent as possible, and that's good design practice for other reasons.)

Typically, in the design phase(s), you'll have a good idea how important performance is. If you need to, you can design for performance from the start (which does not include code-level optimizations).

There's also the developing of efficient coding habits in choosing between two otherwise similar practices. For example, in C++ it's worthwhile typing ++i rather than i++, because it's a trivial thing that can be significantly more efficient sometimes.

Anything more than that should wait until (a) it's clear that improving the performance will pay off, and (b) you know where the hotspots are.

Upvotes: 4

alphadogg
alphadogg

Reputation: 12930

There is one basic truth:

You cannot optimize what you cannot test

Therefore, as other have stated, and especially wrt to performance optimizations, you must write the code to then be able to test it. Moreso, in a large body of code, one algorithm may be the generally fastest one, but given how it inter-relates with other code, it is either a useless optimization which costs you time, or is slower than option 2, 3, ...

However, there is a body of knowledge out there that you can tap into, especially at the conceptual level, that can help you "pre-optimize" your design in a global scale.

Unfortunately, this is one of those debates that has no real closure.

Upvotes: 1

krosenvold
krosenvold

Reputation: 77261

Concentrate on writing code that does exactly what it's supposed to do, and only the required number of times. Optimizing clean, elegant code is usually simple.

Upvotes: 4

EBGreen
EBGreen

Reputation: 37830

It should purely be a return on investment analysis. If you can put a little effort in to design optimization and reap a vast return in performance then do it. Gradually you will get to the point where the return for the amount of effort just doesn't make sense any more.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1504122

Optimise at the design and architecture level early on. Micro-optimise at the implementation level later.

You need to be aware of the performance costs of design decisions you make which will be hard to change later. Implementation can often be tuned later on, which is why it's not worth doing it until you know that it's a problem.

Upvotes: 29

Adrian Grigore
Adrian Grigore

Reputation: 33318

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.

Upvotes: 9

Related Questions