Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
36
14-06.md
36
14-06.md
|
|
@ -9,12 +9,12 @@ good as or better than—sometimes *much* better than—brute-force
|
|||
searching. (For short patterns, you might want to use **REPNZ SCASB,**
|
||||
thereby getting the best of both worlds.)
|
||||
|
||||
Know your data and use your smarts. Don’t stop thinking just because
|
||||
you’re implementing a big-name algorithm; you know more than it does.
|
||||
Know your data and use your smarts. Don't stop thinking just because
|
||||
you're implementing a big-name algorithm; you know more than it does.
|
||||
|
||||
### Further Optimization of Boyer-Moore {#Heading6}
|
||||
|
||||
We can do substantially better yet than Listing 14.3 if we’re willing to
|
||||
We can do substantially better yet than Listing 14.3 if we're willing to
|
||||
accept tighter limits on the data. Limiting the length of the
|
||||
searched-for pattern to a maximum of 255 bytes allows us to use the
|
||||
**XLAT** instruction and generally tighten the critical loop. (Be aware,
|
||||
|
|
@ -35,7 +35,7 @@ about 60 percent faster than Listing 14.3.
|
|||
; Requires that the pattern be no longer than 255 bytes, and that
|
||||
; there be a match for the pattern somewhere in the buffer (ie., a
|
||||
; copy of the pattern should be placed as a sentinel at the end of
|
||||
; the buffer if the pattern isn’t already known to be in the buffer).
|
||||
; the buffer if the pattern isn't already known to be in the buffer).
|
||||
; Tested with TASM.
|
||||
; C near-callable as:
|
||||
; unsigned char * FindString(unsigned char * BufferPtr,
|
||||
|
|
@ -58,14 +58,14 @@ about 60 percent faster than Listing 14.3.
|
|||
public _FindString
|
||||
_FindString proc near
|
||||
cld
|
||||
push bp ;preserve caller’s stack frame
|
||||
push bp ;preserve caller's stack frame
|
||||
mov bp,sp ;point to our stack frame
|
||||
push si ;preserve caller’s register variables
|
||||
push si ;preserve caller's register variables
|
||||
push di
|
||||
sub sp,256 ;allocate space for SkipTable
|
||||
; Create the table of distances by which to skip ahead on mismatches
|
||||
; for every possible byte value. First, initialize all skips to the
|
||||
; pattern length; this is the skip distance for bytes that don’t
|
||||
; pattern length; this is the skip distance for bytes that don't
|
||||
; appear in the pattern.
|
||||
mov di,ds
|
||||
mov es,di ;ES=DS=SS
|
||||
|
|
@ -106,7 +106,7 @@ about 60 percent faster than Listing 14.3.
|
|||
mov bx,sp ;point to SkipTable for XLAT
|
||||
SearchLoop:
|
||||
sub ah,ah ;used to convert AL to a word
|
||||
; Skip through until there’s a match for the first pattern byte.
|
||||
; Skip through until there's a match for the first pattern byte.
|
||||
QuickSearchLoop:
|
||||
; See if we have a match at the first buffer location.
|
||||
REPT 8 ;unroll loop 8 times to reduce branching
|
||||
|
|
@ -132,21 +132,21 @@ about 60 percent faster than Listing 14.3.
|
|||
dec di ;point to next destination byte to compare (SI
|
||||
; points to next-to-rightmost source byte)
|
||||
repz cmpsb ;compare the rest of the pattern
|
||||
jz Match ;that’s it; we’ve found a match
|
||||
; It’s a mismatch; let’s see what we can learn from it.
|
||||
jz Match ;that's it; we've found a match
|
||||
; It's a mismatch; let's see what we can learn from it.
|
||||
inc di ;compensate for 1-byte overrun of REPZ CMPSB;
|
||||
; point to mismatch location in buffer
|
||||
; # of bytes that did match.
|
||||
mov si,[bp+BufferPtr]
|
||||
sub si,di
|
||||
; If, based on the mismatch character, we can’t even skip ahead as far
|
||||
; If, based on the mismatch character, we can't even skip ahead as far
|
||||
; as where we started this particular comparison, then just advance by
|
||||
; 1 to the next potential match; otherwise, skip ahead from this
|
||||
; comparison location by the skip distance for the mismatch character,
|
||||
; less the distance covered by the partial match.
|
||||
mov al,[di] ;get the value of the mismatch byte in buffer
|
||||
xlat ;get the skip value for this mismatch
|
||||
mov cx,1 ;assume we’ll just advance to the next
|
||||
mov cx,1 ;assume we'll just advance to the next
|
||||
; potential match location
|
||||
sub ax,si ;is the skip far enough to be worth taking?
|
||||
jna MoveAhead ;no, go with the default advance of 1
|
||||
|
|
@ -167,9 +167,9 @@ about 60 percent faster than Listing 14.3.
|
|||
Done:
|
||||
cld ;restore default direction flag
|
||||
add sp,256 ;deallocate space for SkipTable
|
||||
pop di ;restore caller’s register variables
|
||||
pop di ;restore caller's register variables
|
||||
pop si
|
||||
pop bp ;restore caller’s stack frame
|
||||
pop bp ;restore caller's stack frame
|
||||
ret
|
||||
_FindString endp
|
||||
end
|
||||
|
|
@ -182,15 +182,15 @@ it as a parameter.
|
|||
|
||||
### Know What You Know {#Heading7}
|
||||
|
||||
Here we’ve turned up our nose at a repeated string instruction, we’ve
|
||||
gone against the grain by comparing backward, and yet we’ve speeded up
|
||||
Here we've turned up our nose at a repeated string instruction, we've
|
||||
gone against the grain by comparing backward, and yet we've speeded up
|
||||
our code quite a bit. All this without any restrictions or special
|
||||
requirements (excluding Listing 14.4)—and without any new information.
|
||||
Everything we needed was sitting there all along; we just needed to
|
||||
think to look at it.
|
||||
|
||||
As Yogi Berra might put it, “You don’t know what you know until you know
|
||||
it.”
|
||||
As Yogi Berra might put it, "You don't know what you know until you know
|
||||
it."
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](14-05.html) [Table of Contents](index.html) [Next](15-01.html)
|
||||
|
|
|
|||
Loading…
Reference in a new issue