
Why clean code is more important than efficient code - DanielRibeiro
http://m.techrepublic.com/blog/programming-and-development/why-clean-code-is-more-important-than-efficient-code/4284
======
humbledrone
> _Without readability and comprehensibility, you cannot easily reuse your
> code._

Without reasonable efficiency, nobody would _want_ to reuse your code. In
fact, one of the hallmarks of reusable code is that it is efficient in a wide
variety of circumstances; frequently the author of an API cannot predict what
it will be used for, and thus must at the very least avoid pathological
inefficiency when possible.

> _I was not thinking about performance, about the efficiency of what I wrote,
> at all; I simply did not want to think about it at the time._

Bad software happens when you don't think about the efficiency of what you're
writing _at all_. This perspective is completely detached from reality; in the
real world, your code runs on a real machine and does real work. Sure, in some
circumstances it's entirely appropriate to write inefficient code, but that's
a decision that should be made after an assessment of the problem at hand. To
intentionally ignore efficiency as a matter of policy is to ignore the facts
of reality.

At the very least, you need to consider the performance impacts of the data
structures you use. In most modern languages, it's not terribly difficult to
use e.g. a hash in place of an array, and in the right circumstances it can
make the difference between usable and unusable software. I can't even count
how many tools I've used that, due to a poor choice of data structure, could
not scale beyond the small data set that their authors tested them against,
and were thus useless beyond a very limited scope.

~~~
biot
I would argue that it depends on the developer. Someone just starting out and
not having a great deal of experience with algorithms, data structures,
security, and the like will need to spend much more time focusing on those
aspects. Their challenge isn't [only] writing elegant, maintainable code...
it's getting their code to work at all at a reasonable level of performance.

Someone who has been writing software for a few decades will be starting out
having already implicitly rejected bad algorithms, unmaintainable designs,
unscalable data structures, and poor security practices. Years of development
has given them an intuitive feel for the best starting point for an efficient,
scalable, and secure design.

Not to mention that anybody with sufficient experience knows to figure out the
overall design first before cracking open the code editor. As such, their
focus should be on keeping their code elegant and maintainable because it will
be built on top of a reasonably performant architecture. And when they
discover areas which need greater efficiency, the ease of refactoring the well
designed architecture is an inherent bonus.

~~~
humbledrone
I agree with that. One thing I didn't mention in my original comment is that I
think that there is often a rough correlation between elegant, readable code
and at least basic efficiency. I tend to think that code that uses the right
data structures looks cleaner. For instance, code using an array instead of a
hash tends to look a little bit funny if it's constantly looking up elements
by a particular attribute. This is especially the case today when so many
excellent data structures and algorithms are already implemented in library
code with nice pretty APIs. (I feel that I should mention, though, that the
authors of those libraries probably worried _a lot_ about efficiency!)

------
JangoSteve
I think this title is a bit link baity. Yes, clean code is important. So is
efficient code. To say one is more important than the other is needlessly
oversimplifying things. How about this? They're both important; and sometimes
one takes precedence over the other depending on the situation and context;
but most of the time, you should just strive for both.

Clean code requires less resources in terms of maintenance, bug fixes, and
extensibility, because it's easier to understand and modify. Efficient code
requires less resources in terms of server maintenance and bug fixes, because
it actually requires less maintenance and is less likely to catch you off
guard by taking your server down.

~~~
Aga
I think the author makes a good point that clean code makes it easier to
refactor for efficiency when proven where the need is real. Going the other
route (making efficient code readable) is a lot harder and tends to get often
"forgotten".

~~~
delinka
Premature optimization and all that.

------
hugh3
_As computing resources continue to grow, efficiency falls further behind
another concern when writing code, though._

I've spent enough time diagonalizing 10,000 by 10,000 matrices to get
frustrated with anyone who claims that efficiency in time and memory ain't
important any more. Maybe not for _your_ code...

~~~
Stormbringer
I've spent enough time reading code written by people who thought that
efficiency was more important than readablility to know that not only are they
_spectacularly_ wrong, but 9 times out of 10 they suck at efficiency but
didn't realise it because their code was so firckin' obtuse.

As soon as their code is made more readable, not only does this make life
easier for the next guy, but it also makes it a lot easier to optimise once it
is clear what it is actually doing.

People who don't want to write readable code seem to subscribe to the belief
that there is only one way to write a particular line of code, yet they could
not be more wrong. For any non-trivial section of code in any non-trivial
language there are dozens, if not _millions_ of different ways of writing it.
Given that, making it unreadable is either maliciousness or incompetence, and
Hanlon's Razor tells me it's probably not malice.

Moreover, most of the time the poor sod who is the "next guy" to read/maintain
the code is _you_. You are the next guy. You are the audience of most of your
coding efforts. If you cannot read your code 6months down the track, then the
only person you're shafting with your bad workmanship is future you.

You _can_ have your cake and eat it to. Code can be both efficient and
readable.

------
6ren
Code is a solution, based on a model of the problem.

Understanding a problem is more important than writing a solution that is
clean in itself. However, we often don't understand a problem immediately.
Writing code (and seeing the results) is one way to quickly gather data about
the problem, and so help understand it.

This is where clean code can help: code that clearly communicates your current
model of the problem is very helpful part of the process. After a break, it
reminds you of the model; someone else inspecting the code can see the model;
it is easier to see where the model is incorrect; it is easier to modify the
code to correct the model; when the problem itself changes, it is easier to
modify the code.

However, there is a trade-off between effort and clarity: it is a mistake to
spend too much time clarifying something that might not be correct (or, if the
problem will change soon, making it incorrect). Just write code that reflects
your understanding of the problem. Regarding efficiency: if you know how to
easily make it more efficient without compromising that (e.g. without making
it convoluted), then of course do it.

Code is not a final product, but a process. The faster you can iterate, the
better it is. (An exception is if you already understand the problem
_perfectly_.)

~~~
jbrechtel
"...it is a mistake to spend too much time clarifying something that might not
be correct.."

I think the problem is that too many people disagree on what is 'too much
time'. Not trying to nit-pick but obviously it is a mistake to spend 'too much
time' doing anything. That's implied in the too much. That may come off as
being pedantic, but I don't mean it to be so. I think defining 'too much time'
is right at the heart of the problem. And it's a hard problem to be sure.

I'd also disagree that the possibility of something being incorrect is a
reason to spend less time clarifying it...I'd say just the opposite.

By clarifying code you're making it easier to comprehend and thus change in
the future. I'd say you should write code with change in mind.

Regarding 'incorrectness' itself...that's the only reason code is ever
changed. Whether the code is fundamentally incorrect (the type I believe you
were referring to) or temporally incorrect, the incorrectness of the code is
always the reason for the change.

~~~
6ren
I agree the exact trade-off is difficult. I just meant clarity is not an
absolute. You shouldn't make a _project_ out of clarifying - it shouldn't be a
driver of what you are doing; instead, given different ways of developing
quickly, you should choose one that gives clearer code. Write it as you see
it, instead of trying to be clever - that is, write in in terms of your
understanding of the problem not beyond it. It's bang per buck: "a little
effort for a lot of clarity" is worth it.

As for the exact trade-off: when you are iterating quickly, it is not
effective to try to nail down these trade-off precisely - you need those
cycles for actual coding!

For that matter, it's also difficult to define what is "clear" - or even what
is "simple". Have you ever tried applying the "Single Responsibility
Principle" thoroughly? It's amazing how many genuine "reasons to change" you
can find - and amazing how less clear it can be. Another example is
dogmatically writing "short methods". Clarity, like "simplicity" - and like
the trade-off you note - is itself extremely hard to pin down precisely.

BTW: reasons to change other than correctness include: making it more
efficient; making it clearer (e.g. refactoring); making it reusable (Brooks'
says it's x3 the work). And, in practice, there's a continuum of correctness,
not true/false, for "better" (more accurate, more reliable) results: e.g. more
accurate search ranking; better collision detection; better webpage rendering;
OS that crashes less often.

~~~
jbrechtel
I'd agree that refactoring for clarity can't reasonably fall under a wide
'correctness' umbrella. Definitely more reasons to change code than
correctness.

I put the word in quotes to try to express a much wider than usual connotation
for the word (air quotes, if you will..). It's a shame that language is all we
have to communicate on the internet.... :)

I also agree that we shouldn't precisely define tradeoffs before continuing on
a single, specific, problem.

I just think that, in the macro sense, we can and should get better at
defining the factors that would inform such a precise weighing of the
tradeoffs for clarify, efficiency, expediency, etc... Doing so would give us
better instincts for single instances where doing a precise comparison would
be absurd.

~~~
6ren
I agree it would be good to improve at weighing trade-offs. This is the
standard method of progress in many fields, systemization of data, the finding
of rules, the development of models - theories, in short. A nice practical
example is Deming's quality management. They used to think you could improve
quality up to a certain point, but beyond that you just have to put up with
some random amount of defects. He showed that with measurement and accurate
models, you can increase quality as much as you like. Is that more or less
your thinking?

But I think there's a fundamental barrier for software, because programs can
differ from one another arbitrarily. This makes it hard to generalize - and
generalization is the essence of theory, rules, systemization, modeling etc. I
assume you'll accept that generalization is crucial, but you'll disagree that
software can vary arbitrarily.

The reason I say this is because if you find regularity in software... you can
automate it. Factor out a common method. Extract a "pattern" into a framework
(or better, in functional programming). Derive one thing from another. It's
like compression: as soon as you notice something that you can generalize, and
construct a theory to model it... you can use that theory to eliminate the
redundancy.

In a deeper sense, programming itself represents theories. And theories (e.g.
of physics) are not generalizable: we don't have a theory of theories, that
enables us to automatically generate the next correct theory. Oh, we can
automatically generate theories, just not correct ones. For that, we need data
to test them, to find out which one is correct. And so the unknown is the
ultimate cause of the problem: we can't generalize what we don't know.

The best you can do is come up with rules of thumb, that help in specific
domains - but they only work there. And if they are really accurate, someone
will encapsulate them in a method, a framework, a library, a language or
operating system, so that programmers don't need to deal with them, and that
pattern disappears from their programs.

And to finish off with one of my favourite quotes, by Alan Turing: _There need
be no real danger of [programming] ever becoming a drudge, for any processes
that are quite mechanical may be turned over to the machine itself._

NB: in practice, there is an _enormous_ amount of repetition in programs (and
parts that are common between different programs). This amounts to ongoing
demand for libraries, frameworks, languages, operating systems, and extra
features for them.

So, it's hard to obtain a _precise weighing of the tradeoffs for clarify,
efficiency, expediency_ when the playing field keeps changing. We can get
better, but not much. It's different in fields like civil engineering, where
materials and techniques don't change often. BTW Another fuel for change in
software is Moore's Law - which enables different techniques to become
favoured that weren't plausible before (like dynamic languages, VMs, etc).

sorry, such a long and self-indulgent response. Maybe it doesn't apply so
strongly to trade-offs (though I think clarity is closely related to theory).
At any rate, it doesn't stop us improving, which is what you suggest.

------
rluhar
I guess "clean code" is in the eye of the beholder. A lot of my work involves
supporting scripts written in an extremely terse language (q
<http://code.kx.com>). Coming from a Java background, the code looks
horrendous, incomprehensible even. But the language is designed for the
analysis of a huge amount of data using concepts from linear algebra. Any
attempt to re-write the code following the tradition "Clean Code" recipe could
result in inefficient code. I think there is a sweet spot for each application
or domain, somewhere between the efficient (but unreadable), "clean" (but
posssibly inefficient) axis. This sweet spot depends on the tools, the problem
set and constraints that the developer is working under.

------
fleitz
There aren't any easy answers in software development because it's an art, not
a science. In some circumstances clean code is better, in some circumstances
efficient code is better and if deadlines and money are involved sometimes a
complete hack job that's both ugly and inefficient is best. Whenever writing
software you have to look at all your available resources, hardware,
developers, money, time and figure out the best way to utilize those
resources. If a hack job will pay for a rewrite and you don't have time to do
it right then do that.

------
fexl
The author wrote: "I wrote code that correlated a short list in one record
with a long list of values that resided in another record, summed values that
matched between the two lists, and presented the result. ... It was all very
clear and clean code. Unfortunately, it turned out to be horrifically
inefficient, though I did not notice this fact at first. It was only later
when I decided I needed to be able to perform this operation hundreds of times
and produce tabular output to show a visible matrix of results that the
failures of that approach became obvious."

This reminds me of an approach I took on a recent project, where I wrote a
variety of ultra-simple routines to look up very specific numbers and results.
These routines would often go out and fetch a rather large file of data, and
crunch that data down to the single result the caller desired. All in all, it
was a _highly_ inefficient way to do things. However, it was not a problem,
because all I had to do was drop in a few caches here and there inside the
routines, and voila, the whole thing became fast enough.

I found it a very liberating approach, because all of my code looked very
"obvious" in its logic. In a few scattered places you see a couple lines of
code to look something up in the cache first, but then it drops down into the
ordinary and extremely clear logic.

The code also had a very nice "lazy", "on-demand", and decentralized feel to
it, with no need for a bunch of gnarly and centralized initialization code.

------
wolfgangK
Because it is easier to make clean code efficient than to clean efficient
code. (I m talking about implementation (in-)efficiencies, not architectural
ones)

~~~
prodigal_erik
Optimizing clean code is easier, but you're gambling that your overloaded
service will only lose credibility slowly enough to give you time to finish
(e.g., Twitter found themselves on very thin ice for a while). Refactoring
efficient code takes more work but doesn't come with that kind of deadline, it
just slows down maintenance in the meantime.

~~~
mnutt
Yeah, it's unfortunate that when your clean but inefficient code falls over,
the engineering department takes all of the blame. But when your efficient but
unclean code doesn't allow you to iterate as quickly, it's harder to place
blame.

------
kaib
This statement is false for people writing large scale distributed systems. It
turns out tens or hundreds of thousands of computers are more expensive than
engineering time. No amount of clean will fix gaping million dollar holes in
the budget.

And given migration of large clusters from one piece of code to another is
expensive you want to think about performance ahead of time.

~~~
rickmb
Isn't the primary requirement for writing a highly scalable distributed system
to have clean and strictly decoupled code? Otherwise scaling becomes a series
of rewrites.

And in that scenario engineering time may be less expensive than tons of iron,
the _passing_ of said time is a killer. In most software project, time is a
bigger issue than money.

------
geophile
This is a false choice, and much of the discussion here is arguing for or
against a strawman. Pick the right algorithm, and your efficiency battle is
mostly over. Code it cleanly and have good tests for it. Then, when you
discover where the actual performance problems are, you can fix them,
transforming clean, correct code to faster, clean, correct code.

------
tychonoff
I'm cleaning up someone else's code that didn't contain a single comment. When
finished, the cost for doing this will exceed the original project (we're
talking man-months here).

After that, I'll worry about correctness and efficiency.

In the mainframe days, we used to have code reviews that forced programmers to
structure things properly, or they'd hear about it in the reviews.

------
cstavish
Taking a solid, well-thought-out approach to problem solving is not premature
optimization. Focusing solely on "cleanliness" of code is highly misguided in
many cases. It's quite possible to write clean code that adeptly solves a
given problem, but in order to do that, efficiency cannot be disregarded.

------
spitfire
I'm going to be the heretic here and say both camps are wrong.

The most reasonable approach is to have clean code with a little sprinkling of
efficient code where it matters. So if you've built a nice cocoa app you don't
need to hand code in assembler each little part of it. Just that main image
processing loop. Even in that case, document it well.

Now let me go a little further and say that clean code and efficient code are
not at all mutually exclusive. If you find a programmer is producing efficient
(dare I say even fast), but un readable code it may be time for them to find
new employment.

It's not really hard, keep your Knuth/Dijkstra/Rivest handy, and refer to them
when needed.

------
becomevocal
When I'm trying to push product out the door, I always fight the urge to
optimize. As a compromise, I try and make it easier for my future self to
optimize later, along with a note in a dedicated 'when you have time' doc.

Sometimes it actually works ;)

------
axman6
Did anyone else find it somewhat ironic that that page looks terrible on wide
screens, and is as such quite difficult to read? Columns are important,
especially when your readers may be dyslexic (Like I am), narrower pieces of
text are far easier to read than 'wall to wall' solid chunks of text.

------
chanux
Clean code is as important as efficient code.

Also I don't believe in the idea that the enhancements of hardware are to put
up with lousy code.

