为什么在正则表达式中输入长度不影响性能,这是怎么实现的呢?
生成的字符串格式如下:128个随机字符,然后是两个括号内的数字,并且这个格式重复多次。
128 radnom characters....(-2435346|45436) 128 radnom characters....(-32525562|-325346)
正则表达式获取括号内的所有数字。以下是模式:
\(([-+]?\d+\|[-+]?\d+)\)
那么比赛将会像这样进行:
-2435346|45436
-32525562|-325346
etc...
这里是进行基准测试的代码。我在生成输入后启动计时器,因为我只想评估匹配时间。
Random rand = new Random();
Func<string> getRandString = // generates 128 random characters.
() => Enumerable.Range(0, 128).Select(x => (char) rand.Next()).Aggregate("", (a, b) => a + b);
Func<int> getRandInteger = () => rand.Next(); // generates random number.
string format = "{0}({1}|{2})";
// Generate the big string.
StringBuilder bigstr = new StringBuilder();
for (int i = 0; i < 100; i++) // repeat 100 times.
{
bigstr.Append(string.Format(format, getRandString(), getRandInteger(), getRandInteger()));
}
string input = bigstr.ToString();
Stopwatch stopwatch = Stopwatch.StartNew();
var matches = Regex.Matches(input, @"\(([-+]?\d+\|[-+]?\d+)\)");
stopwatch.Stop();
Console.WriteLine("Time Elapsed :\t{0}\nInputLength :\t{1}\nMatches Count :\t{2}", stopwatch.Elapsed, input.Length, matches.Count);
如果我重复循环10次,这是我的控制台输出结果。
Time Elapsed : 00:00:00.0004132
InputLength : 1500
Matches Count : 10
如果我重复循环1000
次。
Time Elapsed : 00:00:00.0004373 // seriously?
InputLength : 149937
Matches Count : 1000
如果我重复循环1000000
次。
Time Elapsed : 00:00:00.0004900 // wtf?
InputLength : 149964452
Matches Count : 1000000
如果你不信,请看截图。
这是一种懒惰求值的方式吗?如果是,那么它如何显示匹配项的数量?然而,在调试器中,我可以看到有匹配项。
我的正则表达式模式中是否有特殊的东西使其更快?但是为什么字符串长度不会影响性能呢?我无法理解。
|
。我也不知道为什么要用?
使它变成非贪婪模式。当然,这是多余的。 - M.kazem Akhgary