139 lines
No EOL
7.4 KiB
Markdown
139 lines
No EOL
7.4 KiB
Markdown
---
|
|
title: Michael Abrash's Graphics Programming Black Book, Special Edition
|
|
author: Michael Abrash
|
|
date: '1997-07-01'
|
|
isbn: '1576101746'
|
|
publisher: The Coriolis Group
|
|
category: 'Web and Software Development: Game Development,Web and Software Development:
|
|
Graphics and Multimedia Development'
|
|
chapter: '10'
|
|
pages: 190-193
|
|
---
|
|
|
|
## Chapter 10\
|
|
Patient Coding, Faster Code {#Heading1}
|
|
|
|
### How Working Quickly Can Bring Execution to a Crawl {#Heading2}
|
|
|
|
My grandfather does *The New York Times* crossword puzzle every Sunday.
|
|
In ink. With nary a blemish.
|
|
|
|
The relevance of which will become apparent in a trice.
|
|
|
|
What my grandfather is, is a pattern matcher *par excellence*. You're a
|
|
pattern matcher, too. So am I. We can't help it; it comes with the
|
|
territory. Try focusing on text and not reading it. Can't do it. Can you
|
|
hear the voice of someone you know and not recognize it? I can't. And
|
|
how in the Nine Billion Names of God is it that we're capable of
|
|
instantly recognizing one face out of the thousands we've seen in our
|
|
lifetimes—even years later, from a different angle and in different
|
|
light? Although we take them for granted, our pattern-matching
|
|
capabilities are surely a miracle on the order of loaves and fishes.
|
|
|
|
By "pattern matching," I mean more than just recognition, though. I mean
|
|
that we are generally able to take complex and often seemingly woefully
|
|
inadequate data, instantaneously match it in an incredibly flexible way
|
|
to our past experience, extrapolate, and reach amazing conclusions,
|
|
something that computers can scarcely do at all. Crossword puzzles are
|
|
an excellent example; given a couple of letters and a cryptic clue,
|
|
we're somehow able to come up with one out of several hundred thousand
|
|
words that we know. Try writing a program to do that! What's more, we
|
|
don't process data in the serial brute-force way that computers do.
|
|
Solutions tend to be virtually instantaneous or not at all; none of
|
|
those "N log N" or "N^2"^ execution times for us.
|
|
|
|
It goes without saying that pattern matching is good; more than that,
|
|
it's a large part of what we are, and, generally, the faster we are at
|
|
it, the better. Not always, though. Sometimes insufficient information
|
|
really is insufficient, and, in our haste to get the heady rush of
|
|
coming up with a solution, incorrect or less-than-optimal conclusions
|
|
are reached, as anyone who has ever done the *Times* Sunday crossword
|
|
will attest. Still, my grandfather does that puzzle every Sunday *in
|
|
ink*. What's his secret? Patience and discipline. He never fills a word
|
|
in until he's confirmed it in his head via intersecting words, no matter
|
|
how strong the urge may be to put something down where he can see it and
|
|
feel like he's getting somewhere.
|
|
|
|
There's a surprisingly close parallel to programming here. Programming
|
|
is certainly a sort of pattern matching in the sense I've described
|
|
above, and, as with crossword puzzles, following your programming
|
|
instincts too quickly can be a liability. For many programmers, myself
|
|
included, there's a strong urge to find a workable approach to a
|
|
particular problem and start coding it *right now*, what some people
|
|
call "hacking" a program. Going with the first thing your programming
|
|
pattern matcher comes up with can be a lot of fun; there's instant
|
|
gratification and a feeling of unbounded creativity. Personally, I've
|
|
always hungered to get results from my work as soon as possible; I
|
|
gravitated toward graphics for its instant and very visible
|
|
gratification. Over time, however, I've learned patience.
|
|
|
|
> 
|
|
> I've come to spend an increasingly large portion of my time choosing
|
|
> algorithms, designing, and simply giving my mind quiet time in which to
|
|
> work on problems and come up with non-obvious approaches before coding;
|
|
> and I've found that the extra time up front more than pays for itself in
|
|
> both decreased coding time and superior programs.
|
|
|
|
In this chapter, I'm going to walk you through a simple but illustrative
|
|
case history that nicely points up the wisdom of delaying gratification
|
|
when faced with programming problems, so that your mind has time to chew
|
|
on the problems from other angles. The alternative solutions you find by
|
|
doing this may seem obvious, once you've come up with them. They may not
|
|
even differ greatly from your initial solutions. Often, however, they
|
|
will be much better—and you'll never even have the chance to decide
|
|
whether they're better or not if you take the first thing that comes
|
|
into your head and run with it.
|
|
|
|
#### The Case for Delayed Gratification {#Heading3}
|
|
|
|
Once upon a time, I set out to read *Algorithms*, by Robert Sedgewick
|
|
(Addison-Wesley), which turned out to be a wonderful, stimulating, and
|
|
most useful book, one that I recommend highly. My story, however,
|
|
involves only what happened in the first 12 pages, for it was in those
|
|
pages that Sedgewick discussed Euclid's algorithm.
|
|
|
|
Euclid's algorithm (discovered by Euclid, of Euclidean geometry fame, a
|
|
very long time ago, way back when computers still used core memory) is a
|
|
straightforward algorithm that solves one of the simplest problems
|
|
imaginable: finding the greatest common integer divisor (GCD) of two
|
|
positive integers. Sedgewick points out that this is useful for reducing
|
|
a fraction to its lowest terms. I'm sure it's useful for other things,
|
|
as well, although none spring to mind. (A long time ago, I wrote an
|
|
article about optimizing a bit of code that wasn't even vaguely
|
|
time-critical, and got swamped with letters telling me so. I knew it
|
|
wasn't time-critical; it was just a good example. So for now, close your
|
|
eyes and *imagine* that finding the GCD is not only necessary but must
|
|
also be done as quickly as possible, because it's perfect for the point
|
|
I want to make here and now. Okay?)
|
|
|
|
The problem at hand, then, is simply this: Find the largest integer
|
|
value that evenly divides two arbitrary positive integers. That's all
|
|
there is to it. So warm up your pattern matchers...and go!
|
|
|
|
### The Brute-Force Syndrome {#Heading4}
|
|
|
|
I have a funny feeling that you'd already figured out how to find the
|
|
GCD before I even said "go." That's what I did when reading
|
|
*Algorithms;* before I read another word, I had to figure it out for
|
|
myself. Programmers are like that; give them a problem and their eyes
|
|
immediately glaze over as they try to solve it before you've even shut
|
|
your mouth. That sort of instant response can certainly be impressive,
|
|
but it can backfire, too, as it did in my case.
|
|
|
|
You see, I fell victim to a common programming pitfall, the
|
|
"brute-force" syndrome. The basis of this syndrome is that there are
|
|
many problems that have obvious, brute-force solutions—with one small
|
|
drawback. The drawback is that if you were to try to apply a brute-force
|
|
solution by hand—that is, work a single problem out with pencil and
|
|
paper or a calculator—it would generally require that you have the
|
|
patience and discipline to work on the problem for approximately seven
|
|
hundred years, not counting eating and sleeping, in order to get an
|
|
answer. Finding all the prime numbers less than 1,000,000 is a good
|
|
example; just divide each number up to 1,000,000 by every lesser number,
|
|
and see what's left standing. For most of the history of humankind,
|
|
people were forced to think of cleverer solutions, such as the Sieve of
|
|
Eratosthenes (we'd have been in big trouble if the ancient Greeks had
|
|
had computers), mainly because after about five minutes of brute
|
|
force-type work, people's attention gets diverted to other important
|
|
matters, such as how far a paper airplane will fly from a second-story
|
|
window. |