2010-03-18 61 views

回答

38

絕對。一個Matcher上創建一個預編譯的正則表達式,而String.matches必須在每次執行時重新編譯正則表達式,所以更多的時候,你運行該代碼行變得更加浪費。

5

String.matches內部調用Pattern.matches(regex, str)。 它的問題在於,每次調用它時,都會重新編譯模式,這會花費一些資源。

最好是一次編譯你的模式,然後嘗試匹配它所有你想要的字符串。 我個人使用包含我的我的應用模式的模式類聲明爲final和靜態

+2

「我個人使用包含我的我的應用模式聲明爲final和靜態模式一類。」 最好將模式放在實際使用的類或方法中。這樣,一起更改的代碼就被打包在一起。請參閱[Common Closure Principle](http://c2.com/cgi/wiki?CommonClosurePrinciple)。 – 2014-11-28 14:05:29

+1

的確我同意你的意見。我的意見在4年內發生了變化:-) – chburd 2014-11-28 15:24:47

23

String.matches內部委託給Matcher.matches。

public boolean matches(String regex) { 
    return Pattern.matches(regex, this); 
} 

public static boolean matches(String regex, CharSequence input) { 
    Pattern p = Pattern.compile(regex); 
    Matcher m = p.matcher(input); 
    return m.matches(); 
} 

如果您正在重用的模式對象,然後會有一些性能上的好處。另外當使用模式/匹配器時,您可以使用group您的正則表達式並獲得匹配的部分。

的底線是,如果你有,你將只使用一次,一個正則表達式,你不需要解析您的字符串獲得配套件然後使用。但是如果你打算對多個字符串使用相同的正則表達式,或者你需要基於正則表達式的字符串的一部分創建一個模式,並獲得使用它的匹配器。

8

出於好奇,我做的時間差這個小的考驗。結果發現,使用預編譯模式的比使用String.matches方法的速度快了5倍以上

import java.util.regex.Pattern; 

/** 
* @author Rajind Ruparathna 
*/ 
public class MatchesTest { 
    public static void main(String Args[]) { 
     String first = "@\\{message.headers\\.?([^\\}]*)\\}"; 
     String second = "@\\{message.headers.wolla\\}"; 
     long start, end, total; 
     float avg; 
     int NUM_OF_ITERATIONS = 100; 

     Pattern pattern = Pattern.compile(first); 

     total = 0; 
     start = 0; 
     end = 0; 
     avg = 0; 

     for (int i=0; i< NUM_OF_ITERATIONS; i++) { 
      start = System.nanoTime(); 
      pattern.matcher(second).matches(); 
      end = System.nanoTime(); 
      total = total + (end - start); 
     } 
     avg = total/NUM_OF_ITERATIONS; 
     System.out.println("Duration pre compiled: " + avg); 

     total = 0; 
     start = 0; 
     end = 0; 
     avg = 0; 

     for (int i=0; i< NUM_OF_ITERATIONS; i++) { 
      start = System.nanoTime(); 
      first.matches(second); 
      end = System.nanoTime(); 
      total = total + (end - start); 
     } 
     avg = total/NUM_OF_ITERATIONS; 
     System.out.println("In place compiled: " + avg); 
    } 
} 

輸出(納秒):

持續時間預先編譯的:4505.0

代替編譯:44960.0

P.S.這個測試是一個快速和骯髒的測試,可能不符合性能基準測試的做法。如果你想獲得高度準確的結果,請使用微型基準測試工具。

+1

這是我正在尋找的基準 - 謝謝! – Tadhg 2017-10-05 13:06:48

0

Pattern.compile編譯模式,這樣當你執行metcher.matches,圖案不重複一遍又一遍編譯。 Pattern.compile預編譯它。但是,如果使用string.matches,則每次執行該行時都會編譯該模式。所以,最好使用Pattern.compile。