什么更快:正则表达式还是字符串操作?

35

在性能方面,什么时候应该使用正则表达式而不是字符串操作,反之亦然?


5
简单的问题,简单的答案。如果您想优化性能,那么选择表现更好的选项。 - David Heffernan
4个回答

35

这取决于

虽然字符串操作通常会稍微快一些,但实际性能严重取决于许多因素,包括:

  • 您解析正则表达式的次数
  • 您如何巧妙地编写字符串代码
  • 正则表达式是否预编译

随着正则表达式变得更加复杂,编写等效的字符串操作代码以获得良好性能将需要更多的努力和复杂性。


33

字符串操作总是比正则表达式操作更快。当然,除非您以低效的方式编写字符串操作。

正则表达式必须被解析,并生成用于执行操作的代码,这需要使用字符串操作。在最好的情况下,正则表达式操作可以做到最优化的字符串操作。

正则表达式之所以被使用,并不是因为它们可以比普通字符串操作更快地完成任何事情,而是因为它们可以用很少的代码和合理小的开销来执行非常复杂的操作。


17

我进行了两个函数的基准测试,它们分别被称为FunctionOne (字符串操作)和FunctionTwo (正则表达式)。 它们都应该会获取在'<'和'>'之间的所有匹配项。

基准测试#1:

  • 调用次数:1'000'000
  • 输入:80个字符
  • 持续时间(字符串操作//FunctionOne):1.12秒
  • 持续时间(正则表达式操作//FunctionTwo):1.88秒

基准测试#2:

  • 调用次数:1'000'000
  • 输入:2000个字符
  • 持续时间(字符串操作):27.69秒
  • 持续时间(正则表达式操作):41.436秒

结论:如果以高效的方式编程,字符串操作几乎总是能够击败正则表达式。但是随着问题变得越来越复杂,字符串操作不仅在性能方面,而且在维护方面都越来越难以跟上。

代码FunctionOne

private void FunctionOne(string input) {
    var matches = new List<string>();
    var match = new StringBuilder();
    Boolean startRecording = false;
    foreach( char c in input) {
        if (c.Equals('<')) {
            startRecording = true;
            continue;
        }

        if (c.Equals('>')) {
            matches.Add(match.ToString());
            match = new StringBuilder();
            startRecording = false;
        }

        if (startRecording) {
            match.Append(c);
        }
    }
}

代码函数2

Regex regx = new Regex("<.*?>");
private void FunctionTwo(string input) {
    Match m = regx.Match(input);
    var results = new List<string>();
    while (m.Success) {
        results.Add(m.Value);
        m = m.NextMatch();
    }
}

9
实际答案是,它在很大程度上取决于你正在做什么、以何种方式以及多频繁地进行。 - SLaks
9
你的正则表达式基准测试非常有误,因为你每次都重新编译正则表达式。如果重复使用单个实例,则速度会更快。如果传递 RegexOptions.Compiled,则速度会更快。 - SLaks
你的字符串代码也非常错误;你正在丢弃大量的字符串实例。你可以使用 StringBuilder 让它更快。 (可能还可以通过跟踪索引和连接范围来优化) - SLaks
1
此外,C# 还有字符字面量:'<' - SLaks
1
此外,[^>]* 可能会更快。 - SLaks
显示剩余8条评论

2
我之前在C#中进行了一些分析,比较了以下内容:
1)LINQ to Objects.
2)Lambda表达式。
3)传统的迭代方法。
所有三种方法都进行了测试,包括使用和不使用正则表达式。在我的测试案例中,结论很明显,当在大量文本中搜索字符串时,正则表达式比非正则表达式慢得多。
您可以在我的博客上阅读详细信息: http://www.midniteblog.com/?p=72

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接