Change bold code snippets to inline code blocks

This commit is contained in:
James Gregory 2013-12-31 17:12:29 +11:00
commit 3c76d884ef
185 changed files with 1772 additions and 1772 deletions

View file

@ -10,11 +10,11 @@ chapter: '05'
pages: 115-118
---
We could put a zero byte at the end of our buffer to allow **strstr()**
to work, but why bother? The **strstr()** function must spend time
We could put a zero byte at the end of our buffer to allow `strstr()`
to work, but why bother? The `strstr()` function must spend time
either checking for the end of the string being searched or determining
the length of that string—wasted effort given that we already know
exactly how long our search buffer is. Even if a given **strstr()**
exactly how long our search buffer is. Even if a given `strstr()`
implementation is well-written, its performance will suffer, at least
for our application, from unnecessary overhead.
@ -28,26 +28,26 @@ for our application, from unnecessary overhead.
Given that no C/C++ library function meets our needs precisely, an
obvious alternative approach is the brute-force technique that uses
**memcmp()** to compare *every* potential matching location in the
`memcmp()` to compare *every* potential matching location in the
buffer to the string we're searching for, as illustrated in Figure 5.1.
By the way, we could, of course, use our own code, working with pointers
in a loop, to perform the comparison in place of **memcmp()**. But
**memcmp()** will almost certainly use the very fast **REPZ CMPS**
in a loop, to perform the comparison in place of `memcmp()`. But
`memcmp()` will almost certainly use the very fast `REPZ CMPS`
instruction. However, *never assume!* It wouldn't hurt to use a debugger
to check out the actual machine-code implementation of **memcmp()** from
to check out the actual machine-code implementation of `memcmp()` from
your compiler. If necessary, you could always write your own assembly
language implementation of **memcmp()**.
language implementation of `memcmp()`.
![**Figure 5.1**  *The brute-force searching technique.*](images/05-01.jpg)
Invoking **memcmp()** for each potential match location works, but
Invoking `memcmp()` for each potential match location works, but
entails considerable overhead. Each comparison requires that parameters
be pushed and that a call to and return from **memcmp()** be performed,
be pushed and that a call to and return from `memcmp()` be performed,
along with a pass through the comparison loop. Surely there's a better
way!
Indeed there is. We can eliminate most calls to **memcmp()** by
Indeed there is. We can eliminate most calls to `memcmp()` by
performing a simple test on each potential match location that will
reject most such locations right off the bat. We'll just check whether
the first character of the potentially matching buffer location matches
@ -60,16 +60,16 @@ Figure 5.2.
### Using memchr() {#Heading6}
There's yet a better way to implement this approach, however. Use the
**memchr()** function, which does nothing more or less than find the
`memchr()` function, which does nothing more or less than find the
next occurrence of a specified character in a fixed-length buffer
(presumably by using the extremely efficient **REPNZ SCASB**
(presumably by using the extremely efficient `REPNZ SCASB`
instruction, although again it wouldn't hurt to check). By using
**memchr()** to scan for potential matches that can then be fully tested
with **memcmp()**, we can build a highly efficient search engine that
`memchr()` to scan for potential matches that can then be fully tested
with `memcmp()`, we can build a highly efficient search engine that
takes good advantage of the information we have about the buffer being
searched and the string we're searching for. Our engine also relies
heavily on repeated string instructions, assuming that the **memchr()**
and **memcmp()** library functions are properly coded.
heavily on repeated string instructions, assuming that the `memchr()`
and `memcmp()` library functions are properly coded.
![**Figure 5.2**  *The faster string-searching technique.*](images/05-02.jpg)
@ -94,7 +94,7 @@ let's make it restartable.
As it happens, there's no great trick to putting the pieces of this
search program together. Basically, we'll read in a buffer of data
(we'll work with 16K at a time to avoid signed overflow problems with
integers), search it for a match with the **memchr()/memcmp()** engine
integers), search it for a match with the `memchr()`/`memcmp()` engine
described, and exit with a "string found" response if the desired string
is found.
@ -115,7 +115,7 @@ That's really all there is to it. Listing 5.1 shows the file-searching
program. As you can see, it's not particularly complex, although a few
fairly opaque lines of code are required to handle merging the end of
one block with the start of the next. The code that searches a single
block—the function **SearchForString()—**is simple and compact (as it
block—the function `SearchForString()`—is simple and compact (as it
should be, given that it's by far the most heavily-executed code in the
listing).