• Java中正则匹配性能测试


    工作中经常会用到在文本中每行检索某种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纳秒

  • 相关阅读:
    111
    ZeroClipBoard 复制粘贴插件
    三、新增临时素材
    二、获取AccessToken
    一、微信公众平台的接入微信公众平台的接入
    Jquery.validate的使用
    尝试解决IIS问题一些方法
    匿名类和匿名方法
    泛型类的认知
    发布支持mysql8.0的writer和reader
  • 原文地址:https://www.cnblogs.com/zwm512327/p/3498527.html
Copyright © 2020-2023  润新知