工作中经常会用到在文本中每行检索某种pattern,刚才测试了三种方式,发现实际性能和预想的有区别
方式1:
直接字符串的matches方法,【string.matches("\d+")】
方式2:
先构建一个单行匹配的pattern,然后用这个pattern去match
Pattern p1=Pattern.compile("\d+");
Matcher m=p1.matcher(sar[i]);
方式3:
构建一个可以匹配换行符DOTALL模式的pattern,然后在整个文本中find
Pattern p2=Pattern.compile("\d+",Pattern.DOTALL );
import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TestRe { /** * @param args */ public static void main(String[] args) { String s1="abc"; String s2="123"; //构建一个多行的字符串 StringBuilder stb=new StringBuilder(); for(int i=0;i<10000;i++){ int k=new Random().nextInt()%2; if(k==0){ stb.append(s1+" "); } else{ stb.append(s2+" "); } } Pattern p2=Pattern.compile("\d+",Pattern.DOTALL ); Pattern p1=Pattern.compile("\d+"); String ts=stb.toString(); String[] sar=ts.split(" "); test1(sar); test2(ts,p2); test3(sar,p1); } public static void test1(String[] sar){ long st=System.nanoTime(); List<String> l=new ArrayList<String>(); for(int i=0;i<sar.length;i++){ if(sar[i].matches("\d+")){ l.add(sar[i]); } } System.out.println("1Size"+l.size()); long et=System.nanoTime(); System.out.println("test1:"+(et-st)+"纳秒"); } public static void test3(String[] sar,Pattern p1){ long st=System.nanoTime(); List<String> l=new ArrayList<String>(); for(int i=0;i<sar.length;i++){ Matcher m=p1.matcher(sar[i]); if(m.matches()){ l.add(sar[i]); } } System.out.println("3Size"+l.size()); long et=System.nanoTime(); System.out.println("test3:"+(et-st)+"纳秒"); } public static void test2(String s,Pattern p){ long st=System.nanoTime(); List<String> l=new ArrayList<String>(); Matcher m=p.matcher(s); while(m.find()){ l.add(m.group()); } System.out.println("2Size"+l.size()); long et=System.nanoTime(); System.out.println("test2:"+(et-st)+"纳秒"); } }
下
面是运行结果,方法一竟然性能最低,在很简单的正则表达式或者不需要替换,不需要找出子匹配时,这个方法是我用的最多的,想不到性能最差。
测试一:
1Size4999
test1:53153038纳秒
2Size4999
test2:13393716纳秒
3Size4999
test3:4527045纳秒
测试二:
1Size4941
test1:38807545纳秒
2Size4941
test2:6826025纳秒
3Size4941
test3:3127127纳秒
看起来好像是方法三优于方法二,实则不然,如果把调用次序换下,方法二有会快于方法三,我的猜想是底层调用可能有单例对象什么的。先调用的pattern可能被复用。没做调查
调换后的结果:
测试一:
2Size5093
test2:12792156纳秒
3Size5093
test3:13665544纳秒
1Size5093
test1:56139648纳秒
测试二:
2Size4952
test2:12030397纳秒
3Size4952
test3:20046193纳秒
1Size4952
test1:40124475纳秒