【发布时间】:2011-03-19 21:48:42
【问题描述】:
非缓存:
var sw = Stopwatch.StartNew();
foreach (var str in testStrings)
{
foreach (var pair in flex)
{
if (Regex.IsMatch(str, "^(" + pair.Value + ")$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture))
;
}
}
Console.WriteLine("\nRan in {0} ms", sw.ElapsedMilliseconds); // 76 ms
缓存
var cache = flex.ToDictionary(p => p.Key, p => new Regex("^(" + p.Value + ")$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled));
var sw = Stopwatch.StartNew();
foreach (var str in testStrings)
{
foreach (var pair in cache)
{
if(pair.Value.IsMatch(str))
;
}
}
Console.WriteLine("\nRan in {0} ms", sw.ElapsedMilliseconds); // 263 ms
我不知道为什么当我预编译所有正则表达式时它的运行速度变慢。更不用说flex 上的迭代器也应该更慢,因为它需要做更多的计算。
这可能是什么原因造成的?
实际上,如果我关闭Compiled 开关,它在缓存时会在 8 毫秒内运行。我认为“编译”会在构造正则表达式时编译它。如果没有,什么时候这样做?
【问题讨论】:
-
如果您不在此代码周围放置
for并运行它进行 1M 次左右的迭代,任何测量都可能会淹没在噪音中。 -
它将正则表达式编译为 C# 代码,对吧?生成的代码是在循环外部还是内部 JIT?
-
@Jon:考虑到我在没有循环的情况下得到 263 毫秒,我认为 1M 正在推动它。 5000 次迭代,使用
cache但未编译需要 3282 毫秒。编译需要3663ms。仍然有点慢,但幅度较小。 -
刚发现正则表达式在第一次使用后被缓存在内存中,即使关闭了编译选项。
-
恕我直言,这似乎很奇怪。您可以尝试使用单个正则表达式(不遍历字典),看看是否有任何显着差异?
标签: c# optimization