2014-02-07 60 views
0

我們有一個應用程序,我們需要過濾某些類型的文件。我們認爲正則表達式的方法會比簡單的Strings.endsWith()方法快。但爲了驗證這個假設,我們做了一個小的基準測試。以下是我們所使用的工作代碼:比較String.endsWith(..)和正則表達式相當於

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class Test{ 

     private static Pattern pattern; 
     private static Matcher matcher; 
     private static final String IMAGE_PATTERN = "([^\\s]+(\\.(?i)(jpeg|jpg|png|gif|bmp|css|js))$)"; 

     private static String[] files = {"jpeg","jpg","png","gif","bmp","css","js"}; 

    public static void main(String args[]) throws Exception { 

     pattern = Pattern.compile(IMAGE_PATTERN); 

     //Input Strings 
     String input = args[0]; 
     String[] inputArr = input.split(","); 

     Integer iterations = 10000; 
     Integer i = 0; 

     Long t1 = System.currentTimeMillis(); 

     while(i < iterations){ 

      for (int j = 0; j < inputArr.length; j++) { 
       validateReg(inputArr[j]); 
      } 
      i++; 
     }  
     System.out.println("Time taken using regex:"+(System.currentTimeMillis() - t1)); 

     t1 = System.currentTimeMillis(); 
     i=0; 
     while(i < iterations){ 

      for (int j = 0; j < inputArr.length; j++) { 
       validateStr(inputArr[j]); 
      } 
      i++; 
     } 
     System.out.println("Time taken using .endsWith :"+(System.currentTimeMillis() - t1)); 

    } 

     public static boolean validateReg(final String file){ 

      matcher = pattern.matcher(file); 
      return matcher.matches(); 

     } 

     public static boolean validateStr(final String file){ 

      for (int i = 0; i < files.length; i++) { 

       if(file.endsWith(files[i])){ 
        return true; 
       } 
     } 
      return false; 
     }  
} 

對於輸入abc.jpg,efg.css,jij.jpeg,test.java,best.css,not.gif,f.exe,test.js,su.css,not.js,yes,png

它打印:

Time taken using regex:89 
Time taken using .endsWith :6 

和數字是多次運行相當一致。即使更改while循環的執行順序,結果也是一樣的。看來String.endsWith()比正則表達式相當快。

現在我的問題是:,這個基準測試方法正確地得出這個結論嗎?或者有沒有更好更可靠的方法來測試這種情況?

+1

你爲什麼期望正則表達式的方法更快? 'endsWith'方法有一個非常特殊的工作要做,而正則表達式是通用的。除了其他任何東西,如果使用正則表達式可以像硬編碼版本一樣快地實現'endsWith','endsWith'可能已經被* endsWith'實現* ... –

+0

感謝Jon。我在印象中(雖然錯誤),endsWith使用迭代迭代,而正則表達式在較低的級別。它看起來相反。 – Santosh

回答

0

String.endsWith通過比較比較字符串末尾的字節(字符)來工作。另一方面,Regexp需要更多時間來分析正則表達式,編譯它,構建匹配器並執行它。但是至於你的問題:這個測試大體上是可以的,至少可以顯示regexp和endsWith之間的差異。在更精確的測量中,您應該儘可能選擇開始時間戳,可能會盡快排除循環開銷和結束時間戳,然後執行一些計算(求和週期)。例如:

long t0, t1, tt = 0L; 
for (int i = 0; i < ITERATIONS; i++) { 
    t0 = System.currentTimeMillis(); 
    //- Execute the code its execution time you want to measure here. 
    t1 = System.currentTimeMillis(); 
    tt += (t1 - t0); 
} 
System.out.println("Total time: " + tt + "ms"); 

對於更精確的測量,您可以使用System.nanoTime()

+0

「比較字節(字符)」表明字節和字符是相同的東西,而他們是非常不... –

+0

「比較磚(牆)」表明磚和牆是同一件事情?...原文所暗示的是,實現是比較字節還是字符,它的工作原理和描述一樣。 – Cromax

1

我發現endsWith正常更快。我懷疑需要進行多少測試才能得出結論。

純字符串搜索方法通常比正則表達式更快(不僅僅是在Java中)。