6

MSDN から次のように指定します。

正規表現オブジェクトは、任意のスレッドで作成でき、スレッド間で共有できます。

パフォーマンスのために、クラスを使用するときにスレッド間でインスタンスを共有しない方がよいことがわかりました。RegexThreadLocal

スレッド ローカル インスタンスで約 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();
        }
    }
}
4

1 に答える 1

5

私の調査結果を提示します。

ILSpy正規表現をしましょう。RegexRunnerへの参照が含まれています。Regexオブジェクトが何かと一致すると、RegexRunnerをロックします。同じRegexオブジェクトへの別の同時リクエストがある場合、RegexRunnerの別の一時インスタンスが作成されます。RegexRunnerは高価です。より多くのスレッドがRegexオブジェクトを共有しているため、一時的なRegexRunnerの作成に時間を浪費する可能性が高くなります。マイクロソフトが大規模な並列処理の時代に対処するためにそれを修正することを願っています。

別のこと:パターン文字列をパラメーターとして受け取るRegexクラスの静的メンバー(Match.IsMatch(input、pattern)など)も、同じパターンが異なるスレッドで一致している場合、パフォーマンスが低下する必要があります。Regexは、RegexRunnersのキャッシュを維持します。同じパターンの2つの同時Match.IsMatch()は、同じRegexRunnerを使用しようとし、1つのスレッドが一時的なRegexRunnerを作成する必要があります。

トピックスターターが答えを見つけた質問をここでどのように処理するかを教えてくれてありがとう。

于 2011-09-30T16:04:55.560 に答える