// Uncolored, plain source file: findbook.java
// findbook.java by Steven R. Brandt
// <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 I 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));
}
}
}