0

私が望んでいたこと:単純な正規表現がコンパイルされた正規表現よりも遅く実行されたかどうかを確認し、結果を証明する必要がありました。100000 個のランダムな文字列を生成し、2 つの正規表現 (1 つは単純なもの、もう 1 つはコンパイル済み) を作成し、この 100000 個の文字列セットで一致をチェックすることにしました。また、多くの出力を解決するために、最初に 100000 文字列すべてを取得してコードを実行し、タイミングを記録し、次に同じセットから最初の 80000 文字列を取得して出力を記録し、次に最初の 50000 文字列を取得しました。同じセットから、出力などをログに記録します...

コード:

var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var random = new Random();
int[] reps = new int[] { 1,10,100,1000,2000,5000,8000,10000,20000,50000,80000,100000 };

List<string> strings = new List<string>();
// generating random strings
for (int i = 0; i < reps[reps.Length-1]; i++)
     strings.Add(new string(
                    Enumerable.Repeat(chars, 8)
                              .Select(s => s[random.Next(s.Length)])
                              .ToArray()));

String regexStr = "[AEIOU]{2,3}(QWERTY|ASDFGH|ZXCVBN){}";
Regex regexSimple = new Regex(regexStr);
Regex regexCompiled = new Regex(regexStr, RegexOptions.Compiled);

using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\harshittiwari\Desktop\Assignment1\test2.txt"))
{
       file.WriteLine("numberOfStrings,ticksForSimpleRegex,ticksForComplexRegex");

       List<long> simple = new List<long>();
       List<long> compiled = new List<long>();
       for (int j = reps.Length - 1; j >= 0; j--)
       {
             Stopwatch time1 = Stopwatch.StartNew();
             for (int k = 0; k < reps[j]; k++)
                  regexSimple.Matches(strings[k]);
             time1.Stop();
             simple.Add(time1.ElapsedTicks);
       }

       for (int j = reps.Length - 1; j >= 0; j--)
       {
                    Stopwatch time1 = Stopwatch.StartNew();
                    for (int k = 0; k < reps[j]; k++)
                        regexCompiled.Matches(strings[k]);
                    time1.Stop();
                    compiled.Add(time1.ElapsedTicks);
       }

       for (int j = reps.Length - 1,k=0; j >= 0; j--,k++)
            file.WriteLine(reps[j] + "," + simple[k] + "," + compiled[k]);
}

問題:説明しにくい奇妙な出力が得られます。出力は次のとおりです。

numberOfStrings,ticksForSimpleRegex,ticksForComplexRegex
100000,300368,217506
80000,240373,201553
50000,178212,98878
20000,13362,202933
10000,6417,6377
8000,5868,7408
5000,3737,3142
2000,160473,1921
1000,1351,1883
100,84,141
10,23,21
1,17,17

numberOfStrings=2000 の ticksForSimpleRegex は、numberOfStrings=5000 の場合よりも大幅に大きいことに注意してください。プログラムを実行するたびに、ほぼ同じです。キャッシュの問題が原因ですか、それともコンパイラの最適化が原因ですか? また、出力を一貫させるにはどうすればよいですか? 一貫性があるとは、 ticksForSimpleRegex が降順であることを意味します (基本的なロジック: 文字列の数が減少し、所要時間は減少します)。

ここで言いたいのは、最初は文字列の数を減らしてから、次のように文字列の数を増やしていたということです。

1,..,..
10,..,..
100,..,..
1000,..,..
...
80000,..,..
100000,..,..

ただし、キャッシングの問題がいくつかあることに気づき、現在の順序を使用することにしました。

EDIT1: http://allben.net/post/2009/08/06/Performance-Compiled-vs-Interpreted-Regular-Expressionsを読みました。解釈された(単純な)正規表現の方が時間がかからなかったはずですが、私たちの場合は、これは結果ではありません。なぜそうなのですか?

4

2 に答える 2

2

IsMatch()の代わりに メソッドを使用するMatches()と、コードは収集する必要のある大量のオブジェクトを作成しません (パフォーマンス ヒットが表示されたときに収集される可能性があります)。私はこの方法でかなり一貫した結果を得ているようです。

于 2013-08-16T10:11:49.650 に答える