Change bold code snippets to inline code blocks
This commit is contained in:
parent
f658bfbb40
commit
3c76d884ef
185 changed files with 1772 additions and 1772 deletions
38
05-02.md
38
05-02.md
|
|
@ -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()`.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
|
|
@ -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).
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue