加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

.net – 正则表达式的多线程使用

发布时间:2020-12-14 05:59:36 所属栏目:百科 来源:网络整理
导读:鉴于以下来自MSDN: Regex objects can be created on any thread and shared between threads. 我发现,对于性能,最好不要在使用ThreadLocal类时在线程之间共享Regex实例. 请问有人可以解释为什么线程本地实例的运行速度大约快5倍? 以下是结果(在8核机器上)
鉴于以下来自MSDN:

Regex objects can be created on any thread and shared between threads.

我发现,对于性能,最好不要在使用ThreadLocal类时在线程之间共享Regex实例.

请问有人可以解释为什么线程本地实例的运行速度大约快5倍?

以下是结果(在8核机器上):

Using Regex singleton' returns 3000000 and takes 00:00:01.1005695
   Using thread local Regex' returns 3000000 and takes 00:00:00.2243880

源代码:

using System;
using System.Linq;
using System.Threading;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static readonly string str = new string('a',400);
        static readonly Regex re = new Regex("(a{200})(a{200})",RegexOptions.Compiled);

        static void Test(Func<Regex> regexGettingMethod,string methodDesciption)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var sum = Enumerable.Repeat(str,1000000).AsParallel().Select(s => regexGettingMethod().Match(s).Groups.Count).Sum();
            sw.Stop();
            Console.WriteLine("'{0}' returns {1} and takes {2}",methodDesciption,sum,sw.Elapsed);
        }

        static void Main(string[] args)
        {
            Test(() => re,"Using Regex singleton");

            var threadLocalRe = new ThreadLocal<Regex>(() => new Regex(re.ToString(),RegexOptions.Compiled));
            Test(() => threadLocalRe.Value,"Using thread local Regex");

            Console.Write("Press any key");
            Console.ReadKey();
        }
    }
}

解决方法

发布我的调查结果.

我们是ILSpy Regex.它包含对RegexRunner的引用.当Regex对象匹配某些内容时,它会锁定其RegexRunner.如果对同一个Regex对象有另一个并发请求,则会创建另一个临时RegexRunner实例. RegexRunner价格昂贵.共享Regex对象的线程越多,浪费时间创建临时RegexRunner的机会就越多.希望微软能够解决这个大规模并行时代的问题.

另一件事:Regex类的静态成员将模式字符串作为参数(如Match.IsMatch(input,pattern))也必须在不同线程中匹配相同模式时执行得很糟糕. Regex维护着RegexRunners的缓存.具有相同模式的两个并发Match.IsMatch()将尝试使用相同的RegexRunner,并且一个线程将必须创建临时RegexRunner.

感谢Will让我知道你如何处理主题首发找到答案的问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读