Deduped images

This commit is contained in:
James Gregory 2013-12-30 12:25:34 +11:00
commit 9e52de9586
233 changed files with 128 additions and 128 deletions

View file

@ -52,7 +52,7 @@
<P>String searching is the simple matter of finding the first occurrence of a particular sequence of bytes (the pattern) within another sequence of bytes (the buffer). The obvious, brute-force approach is to try every possible match location, starting at the beginning of the buffer and advancing one position after each mismatch, until either a match is found or the buffer is exhausted. There&#146;s even a nifty string instruction, <B>REPZ CMPS,</B> that&#146;s perfect for comparing the pattern to the contents of the buffer at each location. What could be simpler?</P>
<P>We have some important information that we&#146;re not yet using, though. Typically, the buffer will contain a wide variety of bytes. Let&#146;s assume that the buffer contains text, in which case there will be dozens of different characters; and although the distribution of characters won&#146;t usually be even, neither will any one character constitute half the buffer, or anything close. A reasonable conclusion is that the first character of the pattern will rarely match the first character of the buffer location currently being checked. This allows us to use the speedy <B>REPNZ SCASB</B> to whiz through the buffer, eliminating most potential match locations with single repetitions of <B>SCASB.</B> Only when that first character does (infrequently) match must we drop back to the slower <B>REPZ CMPS</B> approach.</P>
<P>It&#146;s important to understand that we&#146;re assuming that the buffer is typical text. That&#146;s what I meant at the outset, when I said that the information you need may be under your nose.</P>
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/14-01i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>Formally, you don&#146;t know a blessed thing about the search buffer, but experience, common sense, and your knowledge of the application give you a great deal of useful, if somewhat imprecise, information.</I></SMALL>
<TABLE WIDTH="100%"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="5%"><IMG SRC="images/i.jpg"><TD ALIGN="LEFT" VALIGN="TOP" WIDTH="95%"><SMALL><I>Formally, you don&#146;t know a blessed thing about the search buffer, but experience, common sense, and your knowledge of the application give you a great deal of useful, if somewhat imprecise, information.</I></SMALL>
</TABLE>
<P>If the buffer contains the letter &#145;A&#146; repeated 1,000 times, followed by the letter &#145;B,&#146; then the <B>REPNZ SCASB/REPZ CMPS</B> approach will be much slower than the brute-force <B>REPZ CMPS</B> approach when searching for the pattern &#147;AB,&#148; because <B>REPNZ SCASB</B> would match at every buffer location. You could construct a horrendous worst-case scenario for almost any good optimization; the key is understanding the usual conditions under which your code will work.</P>
<P>As discussed in Chapter 9, we also know that certain characters have lower probabilities of matching than others. In a normal buffer, &#145;T&#146; will match far more often than &#145;X.&#146; Therefore, if we use <B>REPNZ SCASB</B> to scan for the least common letter in the search string, rather than the first letter, we&#146;ll greatly decrease the number of times we have to drop back to <B>REPZ CMPS,</B> and the search time will become very close to the time it takes <B>REPNZ SCASB</B> to go from the start of the buffer to the match location. If the distance to the first match is N bytes, the least-common <B>REPNZ SCASB</B> approach will take about as long as N repetitions of <B>REPNZ SCASB.</B></P>