有什么办法可以提高Regex.Replace性能?

时间:2016-12-29 00:23:27

标签: c# .net

我需要进行字符串替换...我只需要处理几个案例:

1) optional case insensitive
2) optional whole words

现在我正在使用_myRegEx.Replace()...如果指定了#1,我添加了RegexOptions.IgnoreCase标志。如果指定了#2,我将搜索词包装在\ b< word> \ b。

这很好,但它真的很慢。使用String.Replace,我的基准测试需要1100ms vs 90ms。显然这样做的一些问题:

1) case insensitive is tricky
2) regex \b<word>\b will handle "<word>", " <word>", "<word> " and " <word> "... string replace would only handle " <word> ".

我已经在使用RegexOptions.Compiled标志。

还有其他选择吗?

1 个答案:

答案 0 :(得分:2)

如果使用已编译的正则表达式,则可以在这种情况下获得明显的改进。老实说,这不是我第一次测量正则表达式性能并且发现编译的正则表达式更慢,即使按照它应该使用的方式使用。

让我们用一个字符串中的\bfast\b替换12345一百万次,使用四种不同的方法,并且花费多长时间 - 在两台不同的PC上:

var str = "Regex.Replace is extremely FAST for simple replacements like that";
var compiled = new Regex(@"\bfast\b", RegexOptions.IgnoreCase | RegexOptions.Compiled);
var interpreted = new Regex(@"\bfast\b", RegexOptions.IgnoreCase);
var start = DateTime.UtcNow;
for (int i = 0; i < 1000000; i++)
{
    // Comment out all but one of these:
    str.Replace("FAST", "12345"); // PC #1: 208 ms, PC #2: 339 ms
    compiled.Replace(str, "12345"); // 1100 ms, 2708 ms
    interpreted.Replace(str, "12345"); // 788 ms, 2174 ms
    Regex.Replace(str, @"\bfast\b", "12345", RegexOptions.IgnoreCase); // 1076 ms, 3138 ms
}
Console.WriteLine((DateTime.UtcNow - start).TotalMilliseconds);

编译正则表达式始终是最慢的正则表达式之一。我并没有像你一样观察string.ReplaceRegex.Replace之间的差异,但是它在同一个球场上。所以在不编译正则表达式的情况下尝试一下。

另外值得注意的是,如果你只有一根巨大的弦乐,Regex.Replace的速度非常快,在我的电脑上花了大约7毫秒的13,000行Pride and Prejudice。