正则表达式 vs 手动比较。哪个更快?

9
在编写脚本引擎时,我有一些函数(伪代码):
function is_whitespace?(char c){
  return c==' ' || c=='\t' || c=='\r' || c=='\n';
}

那么,我的问题是在大多数语言中哪个更快?使用这个还是使用正则表达式

function is_whitespace?(char c){
  return regex_match('\s',c);
}

我主要关注的编程语言是C#,C和Ruby。如果它完全基于平台,也需要考虑。


2
似乎很简单,可以轻松地编写一个快速测试来找出答案。生成一个充满随机字符的文件,并将其通过两个函数。 - Chad Birch
我认为你那里应该用'\s'而不是'\w'。 - sepp2k
是的,没错。不过对于 C# 测试来说,Mono 就足够了。 - Earlz
@sepp2k,对的。我想到了w=whitespace而不是s=space. - Earlz
5个回答

16

当然,相比构建、运行和销毁状态机,对小块内存进行四次比较更快(且几乎不占用内存)。


+1. 注意,更复杂的示例可能更适合使用正则表达式。 - Billy ONeal
4
我的猜测是永远不会,但手写一个正则语言匹配器与编写一个正则表达式相比可能会变得非常复杂。 - danben
1
当然,这假定您构建了自己的“手动比较”引擎,使其不会进行多余的比较。最终,这将归结为状态机。 - danben
@Earlz:首先,有些人倾向于使用正则表达式来处理可以用比较和子字符串检索来实现的事情。其次,任何足够复杂的正则表达式都无法仅通过语言结构进行重写并保持可读性和可支持性。 - wRAR
@Earlz - 对于这个特定的测试,使用正则表达式会过度杀伤。但是正则表达式非常有用...例如,如果您的is_whitespace函数是一个类的一部分,该类执行与正则表达式类似的操作,您可能能够使用几个正则表达式匹配替换整个类内容。但是,如果您只关心裸执行速度,那么对于微不足道的精确匹配来说,使用正则表达式就过度了。 - overslacked
@Earlz:我听说Perl迷喜欢用正则表达式做任何事情(至少其他语言没有像Perl的~=这样的本地构造),但通常有更清晰和更快速的方法来实现。虽然Python程序通常不从性能角度考虑,但.NET正则表达式的实现细节可能会引起噩梦。 - wRAR

4
手动比较执行速度更快,正则表达式比较输入速度更快。请注意,如果您的系统使用Unicode,则您的两种实现并不等效。正则表达式中的\s匹配所有Unicode空白字符,而手动比较仅处理基本ASCII,并且甚至不包括通常也被视为空格的垂直制表符和换页符。如果您正在使用高级语言编写此内容,建议使用已提供的"is_whitespace()"函数,该基本函数几乎始终都会被包含在编程语言库中。因此,最终的答案是“视情况而定”。在某些情况下,使用过程化代码的额外编程工作是合理的。在许多情况下,正则表达式足够快且更易于维护。

这不取决于你的正则表达式实现是否支持Unicode吗?(还有你使用的编程语言。例如,我认为Ruby仍然不支持Unicode) - Earlz
我说:“如果你的系统使用Unicode”。我的意思是编程语言和正则表达式。Ruby 1.8中的正则表达式不支持Unicode,而Ruby 1.9中的正则表达式支持Unicode。 - Jan Goyvaerts

1

在大多数情况下,查找类似空格字符的正则表达式非常快。在主要的正则表达式实现中,有许多人关注性能,并且可能存在其他代码领域的“低挂果”优化。

正则表达式性能不佳的区域是指编写不良的正则表达式。建议尽量避免不必要的回溯、分组和替换。使用类似于“Regex Buddy”或带有“use re debug”的Perl来查看正则表达式所需的分支数量。

以下链接是一些正则表达式性能问题。

如果有疑问,请进行比较计时...

Coding Horor- Regex

Java Performance - Regex


1

在磁盘使用之后,正则表达式几乎总是我在对代码进行性能分析时的瓶颈。即使是像 .split(" ") 这样简单的事情。


0

我不会谈论C#或C,但我不认为在Ruby中非正则表达式形式更快。


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