home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / turbopas / posbm.zip / POSBM.PAS < prev    next >
Pascal/Delphi Source File  |  1989-06-14  |  6KB  |  193 lines

  1. {Benchmark program to demonstrate the speed difference
  2.  between the POS() in Turbo Pascal 4 or 5 brute-force
  3.  and the Boyer-Moore method function POSBM()
  4.  Program Author:  Costas Menico (Dr. Dobbs, Jul 89
  5.  
  6.  And a new function (posCh) added by Toad Hall
  7.  for when you just want to find a single char in a string.
  8.  
  9.  Courtesy of David Kirschbaum, Toad Hall
  10.  (with a slight tweak to show the elapsed time
  11.   in a more understandable form)
  12. }
  13.  
  14. PROGRAM Search;
  15.  
  16. uses  Dos,Crt;
  17.  
  18. {Link in the POSBM Boyer-Moore function }
  19.  
  20. {$F+}
  21. {$L POSBM}
  22.  
  23. FUNCTION posBM(Pat,S : STRING) : BYTE; EXTERNAL;
  24.  
  25. {and the posCh function}
  26. {$L POSCH}
  27.  
  28. FUNCTION posCh(Ch : CHAR; S : STRING) : BYTE; EXTERNAL;
  29.  
  30. {$F-}
  31.  
  32.  
  33. VAR
  34.   Pat,S : STRING;
  35.   Ch : CHAR;
  36.   i,j : INTEGER;
  37.   elapsed : WORD;   {TH}
  38.  
  39. CONST
  40.   LONGLOOP = 2000;
  41.   STARTFLAG = TRUE;
  42.   FINISHFLAG = FALSE;
  43.  
  44. {Prints benchmark timing information }
  45.  
  46. PROCEDURE Tick;
  47.   {Wait until the DOS timer has just ticked a new second.
  48.    This kinda insures we don't get any "second" wraparound.
  49.   }
  50.   VAR
  51.     regs : registers;
  52.     thissec : BYTE;
  53.   BEGIN
  54.     regs.ah := $2C;                      {get current time}
  55.     MsDos(regs);
  56.     thissec := regs.dh;                  {remember this second}
  57.     REPEAT
  58.       regs.ah := $2C;                    {get current time}
  59.       MsDos(regs);
  60.     UNTIL regs.dh <> thissec;            {until a new second}
  61.   END;  {of Tick}
  62.  
  63. PROCEDURE ShowTime(Start : BOOLEAN);
  64.   {v1.1 Rewritten to
  65.       (1) Use Boolean parm to indicate whether Start or Finish time.
  66.       (2) Use local regs.
  67.       (3) Display elapsed time (in decisecs) if Finish.
  68.       (4) Insure we have a "fresh" second before starting.
  69.   }
  70.   VAR  regs : registers;
  71.   BEGIN
  72.     IF Start THEN Tick;                  {wait for a new second}
  73.  
  74.     regs.ah := $2C;                      {get start time}
  75.     MsDos(regs);
  76.     regs.ax := (regs.dh * 100) + regs.dl;  {seconds*100 + deciseconds}
  77.  
  78.     IF Start THEN BEGIN
  79.       Write ('Start ... ');
  80.       elapsed := regs.ax;               {remember start}
  81.     END
  82.     ELSE BEGIN
  83.       elapsed := regs.ax - elapsed;     {elapsed time}
  84.       WriteLn('Finished, decisecs: ', elapsed:6);
  85.     END;
  86.   END;  {of ShowTime}
  87.  
  88.  
  89. BEGIN  {main}
  90.   ClrScr;
  91.  
  92.   {Create a random string of length 255}
  93.  
  94.   Randomize;
  95.   FOR i := 1 TO 255 DO
  96.     S[i] := CHR(Random(255)+1);
  97.   S[0] := CHR(255);
  98.  
  99.   {Initialize a pattern string with the last five characters
  100.    in the random string as the pattern to search for.
  101.   }
  102.   Pat := Copy(S,251,5);
  103.  
  104.  
  105.   {First do a search with the regular POS function}
  106.  
  107.   Writeln('String Search using Brute-Force Method');
  108.  
  109.   ShowTime(STARTFLAG);                  {show Start time,
  110.                                          remember current decisecs}
  111.  
  112.   FOR j := 1 TO LONGLOOP DO
  113.     i := POS(Pat,S);                    {do the search a few times Brute-force}
  114.  
  115.   ShowTime(FINISHFLAG);                 {get finish time,
  116.                                          display elapsed decisecs}
  117.   Writeln('Pattern found at: ', i);     {show string psn}
  118.  
  119.   {Now do search with the POSBM() (Boyer-Moore) function}
  120.  
  121.   Writeln('String Search using Boyer-Moore Method');
  122.  
  123.   ShowTime(STARTFLAG);                  {show Start time,
  124.                                          remember current decisecs}
  125.  
  126.   FOR j := 1 TO LONGLOOP DO
  127.     i := posBM(Pat,S);                  {do search a few times Boyer-Moore}
  128.  
  129.   ShowTime(FINISHFLAG);                 {get finish time,
  130.                                          display elapsed decisecs}
  131.  
  132.   Writeln('Pattern found at: ', i);     {show string psn}
  133.  
  134.  
  135.   {Now to test our posCh function against both the normal
  136.    Pascal POS() and the posBM functions.
  137.   }
  138.  
  139.   FillChar(S[1],255,'a');
  140.   Ch := 'z';
  141.   S[254] := Ch;
  142.   S[0] := CHR(255);
  143.  
  144.   {First do a character search with the regular POS function}
  145.  
  146.   Writeln('Character Search using Brute-Force Method');
  147.  
  148.   ShowTime(STARTFLAG);                  {show Start time,
  149.                                          remember current decisecs}
  150.  
  151.   FOR j := 1 TO LONGLOOP DO
  152.     i := POS(Ch,S);                    {do the search a few times Brute-force}
  153.  
  154.   ShowTime(FINISHFLAG);                 {get finish time,
  155.                                          display elapsed decisecs}
  156.   Writeln('Character found at: ', i);   {show string psn}
  157.  
  158.   {Now do character search with the POSBM() (Boyer-Moore) function}
  159.  
  160.   Writeln('Character Search using Boyer-Moore Method');
  161.  
  162.   ShowTime(STARTFLAG);                  {show Start time,
  163.                                          remember current decisecs}
  164.  
  165.   FOR j := 1 TO LONGLOOP DO
  166.     i := posBM(Ch,S);                  {do search a few times Boyer-Moore}
  167.  
  168.   ShowTime(FINISHFLAG);                 {get finish time,
  169.                                          display elapsed decisecs}
  170.  
  171.   Writeln('Character found at: ', i);     {show string psn}
  172.  
  173.  
  174.   {Now do character search with the posCh() function}
  175.  
  176.   Writeln('Character Search using Toad Hall posCh function');
  177.  
  178.   ShowTime(STARTFLAG);                  {show Start time,
  179.                                          remember current decisecs}
  180.   FOR j := 1 TO LONGLOOP DO
  181.     i := posCh(Ch,S);                  {do search a few times}
  182.  
  183.   ShowTime(FINISHFLAG);                 {get finish time,
  184.                                          display elapsed decisecs}
  185.  
  186.   Writeln('Character found at: ', i);     {show string psn}
  187.  
  188.   Writeln;
  189.   Writeln('DONE .. PRESS ENTER');
  190.   ReadLn;
  191. END.
  192.  
  193.