Compile regular expressions once

Pattern objects compile the regular expressions which are passed to them. (The compilation happens in memory.) If a regular expression is used many times, then this compilation should be performed only once.

Be wary of the these convenience methods, which compile a regular expression each time they are called:

Example

Here's a comparison of the performance of String.matches versus the use of Pattern and Matcher.

An example run (with the HotSpot compiler turned off) gives:

Time for String: 67.693 ms
Time for Pattern: 12.178 ms


import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** JDK 7+. */
public final class FindMatch {

  /**
   Count the number of times the word "assert" occurs in a file.
  
   Compare the execution times of two techniques.
  */
  public static void main (String... aArguments) throws IOException{
    FindMatch findMatch = new FindMatch("assert");
    Path path = Paths.get("C:\\Temp\\InheritanceInterpreter.java");

    Stopwatch stopwatch = new Stopwatch();
    stopwatch.start();
    findMatch.countMatchesUsingString(path);
    stopwatch.stop();
    log("Time for String: " + stopwatch);

    stopwatch.start();
    findMatch.countMatchesUsingPattern(path);
    stopwatch.stop();
    log("Time for Pattern: " + stopwatch);
  }

  public FindMatch(String aTarget){
    fTargetWord = aTarget;
    fPattern = Pattern.compile(fTargetWord);
  }

  int countMatchesUsingString(Path aPath) throws IOException {
    int result = 0;
    try (Scanner scanner =  new Scanner(aPath, ENCODING.name())){
      while (scanner.hasNextLine()){
        String line = scanner.nextLine();
        if( line.matches(fTargetWord) ){
          ++ result;
        }
      }      
    }
    return result;
  }
  
  int countMatchesUsingPattern(Path aPath) throws IOException {
    int result = 0;
    Matcher matcher = fPattern.matcher("");
    try (Scanner scanner =  new Scanner(aPath, ENCODING.name())){
      while (scanner.hasNextLine()){
        String line = scanner.nextLine();
        matcher.reset(line); //reset the input each time
        if (! matcher.find()) {
          ++result;
        }
      }      
    }
    return result;
  }
  
  // PRIVATE 
  private final String fTargetWord;
  private final Pattern fPattern;
  private final static Charset ENCODING = StandardCharsets.UTF_8;

  private static void log(Object aObject){
    System.out.println(aObject);
  }
} 



See Also :
Time execution speed
Would you use this technique?
Yes   No   Undecided   
© 2014 Hirondelle Systems | Source Code | Contact | License | RSS
Individual code snippets can be used under this BSD license - Last updated on September 21, 2013.
Over 2,000,000 unique IPs last year - Built with WEB4J.
- In Memoriam : Bill Dirani -