gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 15:14:57 28 4
gpt4 key购买 nike

鉴于 MSDN 的以下内容:

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



我发现为了性能,它更好 不是 分享一个 Regex使用 ThreadLocal 时线程之间的实例类(class)。

请有人解释为什么线程本地实例的运行速度大约快 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 正则表达式。它包含对 RegexRunner 的引用。当 Regex 对象匹配某些内容时,它会锁定其 RegexRunner。如果对同一个 Regex 对象有另一个并发请求,则会创建另一个 RegexRunner 的临时实例。 RegexRunner 是昂贵的。共享 Regex 对象的线程越多,浪费时间创建临时 RegexRunner 的机会就越大。希望微软能在大规模并行时代解决这个问题。

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

感谢 Will 让我知道您在这里如何处理 topic-starter 已找到答案的问题。

关于.net - 正则表达式的多线程使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7585087/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com