Efficient coding considered harmful?

Doug Gwyn gwyn at smoke.BRL.MIL
Fri Oct 28 05:52:03 AEST 1988


In article <119 at twwells.uucp> bill at twwells.UUCP (T. William Wells) writes:
>It's the damnedest thing, but people whose opinions I otherwise
>respect seem to have this thing about coding efficiently.  They don't
>like it. Worse, they discourage it.

I think it would be more accurate to say that we want to discourage
excessive concern with microefficiency to the detriment of other
important attributes of source code.

>2) "What is more efficient on one machine may well be less efficient
>   on another." Well, this is a good argument for knowing a lot of
>   different machines and adapting one's coding style to the relevant
>   machines, ..

Actually the force of this argument is stronger if you already
appreciate the value of coding for reasonable behavior on almost
any C implementation, rather than "optimum" behavior on just one.

Some people really may never port their code outside the first
system it's compiled for, but many of us do and we simply don't
have time to fine-tune the code in each environment (unless we
will personally accrue enough benefit to justify it).  My own
time is worth much more than any computer's.

>3) "Efficient coding makes obscurer programs."

Certainly going overboard with microefficiency tweaks does.

>	for (i = 0; i < a[j]; ++i) ...
>into
>	for (i = 0, ilast = a[j]; i < ilast; ++i) ...

In most cases, the following can be used:
	for (i = a[j]; --i >= 0; )
which is more efficient and clearer.

(But don't write something like
	for (p = &a[j]; --p >= a; )
which is nonportable.)

>	for (i = 0; i < ALAST; ++i) {
>		... A[i];
>	}
>
>	for (ap = A; ap < &A[ALAST]; ++ap) {
>		... *ap;
>	}
>
>I write it this second way, as a matter of course, because I thought
>about it for a while and decided that this was the appropriate way to
>do it.  I then trained myself into the habit of doing it this way.

This makes a good example of the dangers of overconcern with such
matters.  There are quite a few compilers that, in many cases, will
generate much better code for the first method than for the second,
because they can recognize an opportunity to use vector instructions.
Others will generate essentially the same code for the two methods.
Unless the situation is naturally thought of as involving a pointer
(for example, to a structure member of an array), it may be clearer
to treat array elements as array elements.

>... dividing positive numbers by powers of two should be done with a shift.

No!  Juggling the source code to use bit-oriented operations in an
arithmetic context not only makes the code less portable and harder
to maintain, it can also lead to future errors, when for example a
chunk size is changed to a variable rather than a constant, or to a
non-power-of-two.

>Unless, of course, the programmer remembered to COMMENT.

Comments don't necessarily track the code, and it is unrealistic to
expect every use of the kind of tricks you advocate to be commented.
Besides, the failure may very well result when code is changed
somewhere far from the place of the comment.

I agree that any use of a trick ought to be clearly commented, but
then whenever I find myself doing that I also usually figure out a
good non-tricky way to accomplish the goal and use that instead.



More information about the Comp.lang.c mailing list