Premature Optimization is the root of all evil

Those who know me know that I have fingers in a couple of very different pies. By day I'm a mild-mannered software developer, toiling away in a cubicle. At night I bust out my cape and timer and coach debate. I play and design video games. And on a good day I'll have the chance to play a little guitar.

This post isn't about how great a guy I am (well, not only about how great a guy I am), the point of this is that I've always been the "jack of all trades" type. One of the reasons that this appeals to me is I like to see the interrelationships between these different worlds. Sometimes a particular concept or aphorism from one of my "lives" ends up providing insight into some aspect of the other. I've already mused about how debate made (makes?) me a better coder, but there is plenty of wisdom in the software world that carries over to debate.

Which brings me to this post's title, which is a quotation popularized by Don Knuth (who, coincidentally, is a genius):

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

"Optimization" here is a term of art, so let me do my best to explain this quote to the non-nerd types out there.

"Software Development," "Programming," "Software Engineering," "Coding," etc. What I do has a lot of names. All of them involve the same fundamental task: Giving a computer at list of commands. These commands are written in "code" that the computer can understand, since computers can't understand commands like "Sort this list of names alphabetically, please".

Anyway, say I want to use a computer to add up all the numbers between 1 and 100. Forget why I'd want to do this for the time being, just assume that that's my goal. Let's look at two different ways I could tell the computer to do this, in code (well, not really in code, but close enough so you get the idea):

First approach, I can add up the numbers one at a time

Declare a new variable "Sum"
For each number i between 1 and 100:
Sum = sum + i;
print Sum

But it turns out there's a faster way to do this. In fact, there's a formula

Print (100 * (100+1)) / 2

If I use the formula, the computer can finish the calculation a lot faster, since it takes it a lot less time to do a one "multiply", one "add", and one "divide" than 100 "adds."

This is a very simple optimization. I could go even further: do a right-shift instead of a divide-by-two, re-code this section in machine language, blah blah blah. But look at the first optimiztion... sure it goes faster, but it conveys less information. Look at the first sample and it's patently obvious that the value I'm interested in is the sum of all numbers between 1 and 100. The second sample though just "looks like a formula." It's not clear from a glance whether I want the sum of 100 numbers or something else entirely.

My code has become less readable, which is one of the main trade-offs involved in optimization. That's (part of) Knuth's point. You don't take every last opportunity to make your program faster, because soon your code turns into an unreadable mess. First make your code clear and readable (and working), then optimize the bottlenecks that make it run slowly. The "premature" in premature optimization means going after "small efficiencies" blindly, without attempt to determine where a program is most inefficient.

Today's topic, if you haven't guessed, is delivery. And if you haven't yet caught on to my metaphor, let me give you a few hypothetical examples of "premature optimization" I've seen:

-The debater who flies through cards (on the edge of clarity) only to stutter and stammer and "umm" their way through anything not pre-written.
-The debater who uses all kinds of annoying abbreviations like "Tix" and "Condo" because they are "more effficient," but will fill up their speech with meaningless "at the point at which"-es
-The debater who has all the annoying artifacts of "speed reading" (double breathing, monotone, too loud/too soft) without actually, you know, being fast
-Not naming new pieces of paper as they are introduced. "Next off!" instead of "Next off is India Deal Good!"

All of these are premature optimizations. They are actions that
technically increase speed or efficiency, but either are incredibly annoying, make it harder to flow, and/or ignore a huge inefficeincy somewhere else.

Allow me now to say something that is obvious, totally boring, completely uncontroversial. The point of speed reading is to convey the maximum information per unit of time. That's it. If you focus on the "small efficiencies" so far as to reduce the amount of information you convey, you fail. Plain and simple.

So before you get in the habit of saying "Idso 8" instead of "Idso in Oh Eight" (two syllables!), focus on the big efficiencies. Where are you reading redundant cards? How can you remove that 3-4 seconds of "Ummmm." in between analytical arguments? If you aren't actively analyzing your delivery to see where your bottlenecks are (triage, once again), you are reduced to randomly picking up habits from other debaters/coaches in a blind attempt at "fast." And you end up sounding like a tool.

Root of all evil indeed.

No comments: