abrash-black-book/05-05.md
2013-12-30 20:26:41 +11:00

66 lines
No EOL
4.5 KiB
Markdown

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.
------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
![](images/i.jpg) *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.
------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
![](images/i.jpg) *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?