78 lines
5.1 KiB
Markdown
78 lines
5.1 KiB
Markdown
------------------------ --------------------------------- --------------------
|
||
[Previous](05-04.html) [Table of Contents](index.html) [Next](06-01.html)
|
||
------------------------ --------------------------------- --------------------
|
||
|
||
It might also be worth converting the search engine to assembly for
|
||
searches performed entirely in memory; with the overhead of file access
|
||
eliminated, improvements in search-engine performance would translate
|
||
directly into significantly faster overall performance. One such
|
||
application that would have much the same structure as Listing 5.1 would
|
||
be searching through expanded memory buffers, and another would be
|
||
searching through huge (segment-spanning) buffers.
|
||
|
||
And so we find, as we so often will, that optimization is definitely not
|
||
a cut-and-dried matter, and that there is no such thing as a single
|
||
“best” approach.
|
||
|
||
------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||
 *You must know what your application will typically do, and you must know whether you’re more concerned with average or worst-case performance before you can decide how best to speed up your program—and, indeed, whether speeding it up is worth doing at all.*
|
||
------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
By the way, don’t think that just because very large block sizes don’t
|
||
much improve performance, it wasn’t worth using restartable blocks in
|
||
Listing 5.1. Listing 5.1 runs more than three times more slowly with a
|
||
block size of 32 bytes than with a block size of 4K, and any
|
||
byte-by-byte approach would surely be slower still, due to the overhead
|
||
of repeated calls to DOS and/or the C stream I/O library.
|
||
|
||
Restartable blocks do minimize the overhead of DOS file-access calls in
|
||
Listing 5.1; it’s just that there’s no way to reduce that overhead to
|
||
the point where it becomes worth attempting to further improve the
|
||
performance of our relatively efficient search engine. Although the
|
||
search engine is by no means fully optimized, it’s nonetheless as fast
|
||
as there’s any reason for it to be, given the balance of performance
|
||
among the components of this program.
|
||
|
||
### Always Look Where Execution Is Going {#Heading10}
|
||
|
||
I’ve explained two important lessons: Know when it’s worth optimizing
|
||
further, and use restartable blocks to process large data sets as a
|
||
series of blocks, with each block handled at high speed. The first
|
||
lesson is less obvious than it seems.
|
||
|
||
When I set out to write this chapter, I fully intended to write an
|
||
assembly language version of Listing 5.1, and I expected the assembly
|
||
version to be much faster. When I actually looked at where execution
|
||
time was going (which I did by modifying the program to remove the calls
|
||
to the **read()** function, but a code profiler could be used to do the
|
||
same thing much more easily), I found that the best code in the world
|
||
wouldn’t make much difference.
|
||
|
||
------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||
 *When you try to speed up code, take a moment to identify the hot spots in your program so that you know where optimization is needed and whether it will make a significant difference before you invest your time.*
|
||
------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
As for restartable blocks: Here we tackled a considerably more complex
|
||
application of restartable blocks than we did in Chapter 1—which turned
|
||
out not to be so difficult after all. Don’t let irregularities in the
|
||
programming tasks you tackle, such as strings that span blocks, fluster
|
||
you into settling for easy, general—and slow—solutions. Focus on making
|
||
the inner loop—the code that handles each block—as efficient as
|
||
possible, then structure the rest of your code to support the inner
|
||
loop.
|
||
|
||
Programming with restartable blocks isn’t easy, but when speed is an
|
||
issue, using restartable blocks in the right places more than pays for
|
||
itself with greatly improved performance. And when speed is *not* an
|
||
issue, of course, or in code that’s not time-critical, you wouldn’t
|
||
dream of wasting your time on optimization.
|
||
|
||
Would you?
|
||
|
||
------------------------ --------------------------------- --------------------
|
||
[Previous](05-04.html) [Table of Contents](index.html) [Next](06-01.html)
|
||
------------------------ --------------------------------- --------------------
|
||
|
||
* * * * *
|
||
|
||
Graphics Programming Black Book © 2001 Michael Abrash
|