C# 记录正则表达式查找匹配所用的时间时发生冲突的记录

C# 记录正则表达式查找匹配所用的时间时发生冲突的记录,c#,.net,regex,performance,C#,.net,Regex,Performance,我想要的:无论简单正则表达式是否比编译正则表达式运行得慢,我都必须看到并证明结果。我决定生成100000个随机字符串,生成两个正则表达式(一个简单,一个编译),并在这100000个字符串集中检查匹配项。另外,为了有许多输出需要解析,我所做的是最初我获取所有100000个字符串并运行代码并记录计时,然后我从同一集中获取前80000个字符串并记录输出,然后从同一集中获取前50000个字符串并记录输出,依此类推 代码: var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

我想要的:无论简单正则表达式是否比编译正则表达式运行得慢,我都必须看到并证明结果。我决定生成100000个随机字符串,生成两个正则表达式(一个简单,一个编译),并在这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=2000的ticksForSimpleRegex明显大于numberOfStrings=5000的ticksForSimpleRegex。每次我运行这个程序,它或多或少都是一样的。是因为缓存问题还是编译器优化?另外,我应该如何使输出一致?所谓一致性,我的意思是ticksForSimpleRegex应该是降序的(基本逻辑:字符串的数量减少,所花费的时间应该减少。)

这里我还想说的是,起初我读的字符串数量较少,然后读的字符串数量较多,比如:

1,..,..
10,..,..
100,..,..
1000,..,..
...
80000,..,..
100000,..,..
然而,我意识到一些缓存问题,并决定按照现在的顺序进行


EDIT1:我读到他们说taht解释(简单)正则表达式应该花费更少的时间,但是在我们的例子中,这不是结果。为什么会这样?

当使用
IsMatch()
方法而不是
Matches()
时,代码不会创建大量需要收集的对象(并且可能在看到性能命中时收集)。通过这种方式,我似乎得到了相当一致的结果。

当使用
IsMatch()
方法而不是
Matches()
时,代码不会创建大量需要收集的对象(当您看到性能命中时,可能会收集这些对象)。我似乎通过这种方式得到了相当一致的结果。

除了C.Evenhui的答案之外
我得到了我的答案,关于为什么垃圾收集器每次都在2000或1000的时候出现。原因是对象和对象大小保持不变,匹配和正则表达式,堆大小保持不变。这就是垃圾收集器只在那个时候被填满的原因。如果我更改随机字符串的大小,那么这可能会有所不同


EDIT1的答案是,在上述基准测试中,5000个不同的正则表达式和编译和解释的正则表达式的基准测试。我们使用的是1个正则表达式。这就是说,很明显,如果您有许多正则表达式,那么最好使用解释正则表达式。如果您有一个简单的正则表达式,并且必须在许多字符串上测试它,那么除了C.Evenhuis的答案之外,还可以使用编译的正则表达式
我得到了我的答案,关于为什么垃圾收集器每次都在2000或1000的时候出现。原因是对象和对象大小保持不变,匹配和正则表达式,堆大小保持不变。这就是垃圾收集器只在那个时候被填满的原因。如果我更改随机字符串的大小,那么这可能会有所不同


EDIT1的答案是,在上述基准测试中,5000个不同的正则表达式和编译和解释的正则表达式的基准测试。我们使用的是1个正则表达式。这就是说,很明显,如果您有许多正则表达式,那么最好使用解释正则表达式。如果您有一个简单的正则表达式,并且必须在许多字符串上测试它,那么使用编译的正则表达式

这似乎可以获得一致的结果。我编辑了我的答案——我认为所有这些对象在某些时候都是由垃圾收集器收集的,清理所需的时间被添加到您的测量值中。您可以尝试保留原始代码并强制执行
GC.Collect()
,看看这是否会改变任何内容。+1用于指出如何获得一致的结果。为什么垃圾收集器在2000或1000个子字符串上执行它的工作。我还不清楚。另外,如果你能提供一些关于编辑的见解,那就太好了。我得到了我的答案,关于为什么垃圾收集器每次都在2000或1000的时候工作。原因是对象和对象大小保持不变,匹配和正则表达式,堆大小保持不变。这就是垃圾收集器只在那个时候被填满的原因。如果我改变随机字符串的大小,那么这可能会有所不同。我不知道确切的GC规则,所以我很高兴你找到了这个规则。我只是解释了为什么会得到不一致的结果,并发现只有使用
IsMatch
才能使脚本生成更少的死区对象。恐怕我不能帮你解释为什么编译的正则表达式有时会比较慢,这是一个完全不同的问题。这似乎能得到一致的结果。我编辑了我的答案——我认为所有这些对象在某些时候都是由垃圾收集器收集的,清理所需的时间被添加到您的测量值中。您可以尝试保留原始代码并强制执行
GC.Collect()
,看看这是否会改变任何内容。+1用于指出如何获得一致的结果。为什么垃圾收集器在2000或1000个子字符串上执行它的工作。我还不清楚。另外,如果你能提供一些关于编辑的见解,那就太好了。我得到了我的答案,关于为什么垃圾收集器每次都在2000或1000的时候工作。原因是对象和对象大小保持不变,匹配和正则表达式,堆大小保持不变。这就是垃圾收集器只在那个时候被填满的原因。如果我改变随机字符串的大小,那么这可能会有所不同。我不知道确切的GC规则,所以我很高兴你找到了这个规则。我只是解释了为什么你得到了不一致的结果,发现只有usi
1,..,..
10,..,..
100,..,..
1000,..,..
...
80000,..,..
100000,..,..