// Uncolored, plain source file:  findbook.java
//    <p>
//    An example file explaining how to use
//    com.stevesoft.pat, com.stevesoft.pat.wrap,
//    and com.stevesoft.pat.apps
//    <p>
//    This software comes without express or implied warranty.
//    No claim is made about the suitability of this software for
//    any purpose and neither we nor SteveSoft shall be liable for
//    damages suffered by the user of this software.
import com.stevesoft.pat.*;
// This program is a speed test for finding text. // Which goes faster on your machine/java version pair, the // indexOf method of String or the search method of Regex? // // I've had to work on both my package and the text since I // originally put this on the web, java 1.1.4 seems to be // faster. // // If you want a bit more speed, you can invoke the SkipBMH searcher // directly. It just searches for substrings and doesn't have the // overhead of Regex because it can't do as much -- but it is still // more versatile than String's indexOf because it can, optionally, // ignore case. // // In any event, the timings will vary with each run and you should // run this experiment a few times to get a good idea of which routine // is fastest.
// When java 1.1.6 came out it was necessary to modify this example // extensively. First, because of the jit, the value of imax needed // to be drastically increased. Secondly, two optimizations (that // take effect even without -O) caused the loop that tested the // speed of the String.indexOf method to appear to execute in zero // time. // Optimization one: I needed to make the "nothing" class to trick the // compiler into thinking that I was using the result of indexOf. // Without this, the loop in which it is called gets optimized away. // Optimization two: I needed to have two slightly different Strings // and to alternate between them on successive searches. Without doing // this, java 1.1.6 is smart enough to take the call to indexOf outside // the loop, and thus the loop iterates only on the doNothing() method. // Even aside from this, the indexOf method is a little // faster now, and I had to go back and re-optimize SkipBMH so that I // could consistantly win race #3 on the Windows platform. class nothing { public void doNothing(int x) {} public void doNothing(boolean x) {} }
public class findbook { public static void main(String[] unused) { while(true) race(); } public static void race() { nothing n=new nothing(); // A random large number... int imax = 100000; new Regex(); // Print startup message. String[] pats = new String[]{"book","Java book","that Java book"}; String txt = "I've checked upstairs. "+ "I've looked between the old newspapers in the living room. "+ "I've looked at the office bookshelf. "+ "I've searched through that big pile in attic. "+ "I've rumaged around in the basement, the bedroom, and the kitchen. "+ "I've even looked under the refrigerator. "+ "Now where on earth did I put that Java book?"; String[] txts = new String[]{"One: "+txt,"Two: "+txt};
for(int j=0;j<pats.length;j++) { System.out.println("\n\nRace #"+(j+1)); String pat = pats[j]; System.out.println("Look for this string ==>"+pat+"<=="); Regex r = new Regex(pat); r.optimize(); SkipBMH sbmh = new SkipBMH(pat); // prove that it gets the same answer as indexof r.search(txt); if(r.matchedFrom() != txt.indexOf(pat)) throw new Error("Regex didn't work!"); if(sbmh.search(txt) != txt.indexOf(pat)) throw new Error("SkipBMH didn't work!"); // try to prevent garbage collection from // interfering with the timing test. System.gc(); // and they're off... long t1 = System.currentTimeMillis(); for(int i=0;i<imax;i++) { /* Of the following three ways of writing this next * line, only one of them executes in non-zero time. * In the other two cases, the call to indexOf is * apparently moved outside the loop. */ n.doNothing(txts[i%2].indexOf(pat)); //txts[i%2].indexOf(pat); //n.doNothing(txt.indexOf(pat)); } long t2 = System.currentTimeMillis(); for(int i=0;i<imax;i++) n.doNothing(r.search(txts[i%2])); long t3 = System.currentTimeMillis(); for(int i=0;i<imax;i++) n.doNothing(sbmh.search(txts[i%2])); long t4 = System.currentTimeMillis(); System.out.println("Time for String.indexOf="+(t2-t1)); System.out.println("Time for Regex.search="+(t3-t2)); System.out.println("Time for SkipBMH.search="+(t4-t3)); } } }