equal
  deleted
  inserted
  replaced
  
    
    
|      1 // A case of catastrophic backtracking in Java 8 |         | 
|      2 //----------------------------------------------- |         | 
|      3 // |         | 
|      4 // regexp: (a*)*b |         | 
|      5 // strings: aa.... |         | 
|      6 // |         | 
|      7 // compile:    javac catastrophic.java |         | 
|      8 // call with:  java catastrophic |         | 
|      9 // |         | 
|     10 // IMPORTANT:  |         | 
|     11 // Java 9 improved its regex matching engine. |         | 
|     12 // This example is now much faster. |         | 
|     13 // |         | 
|     14  |         | 
|     15 import java.util.regex.*; |         | 
|     16  |         | 
|     17 public class catastrophic { |         | 
|     18     public static void main(String[] args) { |         | 
|     19 	 |         | 
|     20         //we always run all the tests twice -> to warmup of the JVM |         | 
|     21         for (int runs = 0; runs < 2; runs++) { |         | 
|     22              |         | 
|     23             Pattern pattern = Pattern.compile("(a*)*b"); |         | 
|     24              |         | 
|     25             // Run from 5 to 28 characters |         | 
|     26             for (int length = 5; length < 28; length++) { |         | 
|     27                  |         | 
|     28                 // Build input of specified length |         | 
|     29                 String input = ""; |         | 
|     30                 for (int i = 0; i < length; i++) { input += "a"; } |         | 
|     31                  |         | 
|     32                 // Measure the average duration of two calls...   |         | 
|     33                 long start = System.nanoTime(); |         | 
|     34                 for (int i = 0; i < 2; i++) { |         | 
|     35                     pattern.matcher(input).find(); |         | 
|     36                 } |         | 
|     37  |         | 
|     38                 // Print out time |         | 
|     39                 System.out.println(length + " " + input + ": "  |         | 
|     40                        + ((System.nanoTime() - start) / 2000000000d)  |         | 
|     41                        + "s"); |         | 
|     42             } |         | 
|     43         } |         | 
|     44     } |         | 
|     45 }  |         |