zoukankan      html  css  js  c++  java
  • 一起谈.NET技术,浅谈提升C#正则表达式效率 狼人:

      说到C#的Regex,谈到最多的应该就是RegexOptions.Compiled这个东西,传说中在匹配速度方面,RegexOptions.Compiled是可以提升匹配速度的,但在启动速度上,使用了RegexOptions.Compiled情况下,通常会使启动速度慢许多,据说最多是60倍。

      进行一组测试,有测试数据,才有讨论依据。

      第一步,帖上测试硬件信息(呵呵,硬件有点烂:()

      第二步,

      a.测试在没有使用RegexOptions.Compiled项时候的情况,随意使用一些内容,然后循环一万次实例化正则表达式对象来匹配这些内容。

    代码
    protected void Page_Load(object sender, EventArgs e)
    {
    WebClient webClient
    = new WebClient();
    string content = webClient.DownloadString("http://www.cnblogs.com/tmyh/archive/2010/09/29/sqlindex_01.html");

    Stopwatch watcher
    = new Stopwatch();
    watcher.Start();

    int i = 10000;
    while (i > 0)
    {
    Regex rgx
    = new Regex("<div>.+?</div>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
    bool b1 = rgx.IsMatch(content);

    Regex rgx2
    = new Regex("<p>.+?</p>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
    bool b2 = rgx2.IsMatch(content);

    i
    --;
    }
    Response.Write(
    string.Concat("<div>", watcher.Elapsed.TotalSeconds.ToString("f7"), "</div>"));
    }

      执行发现,内存使用情况为39,760K。输出的执行时间为3.7954446秒(刷了几次,取最快的那次)

      b.测试在使用了RegexOptions.Compiled项时候的情况,随意使用一些内容,然后循环一万次实例化正则表达式对象来匹配这些内容。

    代码
    protected void Page_Load(object sender, EventArgs e)
    {
    WebClient webClient
    = new WebClient();
    string content = webClient.DownloadString("http://www.cnblogs.com/tmyh/archive/2010/09/29/sqlindex_01.html");


    Stopwatch watcher
    = new Stopwatch();
    watcher.Start();

    int i = 10000;
    while (i > 0)
    {
    Regex rgx
    = new Regex("<div>.+?</div>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
    bool b1 = rgx.IsMatch(content);

    Regex rgx2
    = new Regex("<p>.+?</p>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
    bool b2 = rgx2.IsMatch(content);

    i
    --;
    }
    Response.Write(
    string.Concat("<div>", watcher.Elapsed.TotalSeconds.ToString("f7"), "</div>"));
    }

      执行发现,内存使用情况为42,956K。输出的执行时间为43.3090937秒(刷了几次,取最快的那次)

      从a和b的测试中发现,不妥当地使用此选项,效率是极其低下的,尤其如果在WEB程序上,如果这个页面有大流量请求的话,那会有点不堪设想。我们在正常使用中,极大量文本处理的情况似乎比较少出现,基本上不能体现出RegexOptions.Compiled的所在匹配速度优势,所以通常建议不使用此项。(当然,在正常情况下,我们也不会在每个循环中都new一个正则表达式对象,我们可能会选择static一个)

      第三步,使用传说中的Regex.CompileToAssembly来编译正则表达式,再进行测试。这个,得自己写个编译小程序,帖上本人自己写的一个。点击下载

      与第二步相同的正则表达式Pattern,用这个工具生成dll后,引用到项目。测试执行,发现执行的内存使用情况与第二步的a差不多,速度也相差不多。当然,在这里,这种测试方案,可能看不出这种预编译的正则表达式的效率优点,事实上,它应该能够有更高的执行效率与匹配速度,最好使用多线程与多请求来进行测试。

      在此将其封装到DLL中,这将使最终的程序占用的内存更少,而不必装载使用RegexOptions.Compiled编译正则表达式的包,装载的速度也就得到了提升,同时也拥有了RegexOptions.Compiled的匹配速度优势。另外,也提高了需要一直复用的正则表达式的复用率。缺点,就是比较麻烦,而且只有固定的正则表达式能够这样使用。(关于如何使用Regex.CompileToAssembly,似乎也没多少能够解说的,就三两行代码,下载便知)

      似乎并无深入谈到原理,不过,也并不重要,我们只要经过测试,知道怎么使用能够更好就行了。在此,个人的建议是,通常都不要使用RegexOptions.Compiled,即使要在代码中使用,也应该使用static变量。

      如果真有那么大文本要用的时候,我相信,这个正则表达式也不可能是动态的,固定的正则,我们就使用Regex.CompileToAssembly来先编译成DLL再引用到项目中,即能提供效率,也提高了复用率。

  • 相关阅读:
    Read-Copy Update Implementation For Non-Cache-Coherent Systems
    10 华电内部文档搜索系统 search04
    10 华电内部文档搜索系统 search05
    lucene4
    10 华电内部文档搜索系统 search01
    01 lucene基础 北风网项目培训 Lucene实践课程 索引
    01 lucene基础 北风网项目培训 Lucene实践课程 系统架构
    01 lucene基础 北风网项目培训 Lucene实践课程 Lucene概述
    第五章 大数据平台与技术 第13讲 NoSQL数据库
    第五章 大数据平台与技术 第12讲 大数据处理平台Spark
  • 原文地址:https://www.cnblogs.com/waw/p/2163150.html
Copyright © 2011-2022 走看看