使用正则表达式的性能开销/改进

时间:2012-01-20 07:26:52

标签: java regex string performance full-text-search

如果我需要检查文本(字符串)中是否存在单词A或单词B,如果我这样做,是否存在性能差异:

if(text.contains(wordA) || text.contains(wordB))

使用一些搜索字符串的正则表达式?
它是否依赖于正则表达式格式?
或者只是品味问题?

更新
如果text.contains(wordA)false,则会评估text.contains(wordB) 这意味着contains将被调用两次。

我在想,如果在性能方面,正则表达式可能比调用contains两次更好。

5 个答案:

答案 0 :(得分:4)

您清楚地表达了您的意图的代码,比正则表达式更具可读性,并且可能更快。

无论如何,这部分代码导致任何重大性能问题的概率非常低。所以我不担心这里的性能,而是关于可读性和可维护性。

答案 1 :(得分:4)

虽然正则表达式的表现较低,但它具有更强的表达能力,而且往往更为重要。例如。

 "performance".contains("form") // is true

这可能不是你想要的小麦"字"相反,你可以有一个模式

 "\\bform\\b"

这只会匹配字符串中可以位于开头或结尾的完整单词。

答案 2 :(得分:3)

是的,他们是不同的。包含各种数组操作以查找单词,正则表达式使用不同的逻辑,因此它会有所不同,性能甚至会根据您使用正则表达式匹配的方式而改变。

会有意义吗?这很难说。但你应该意识到最好的事情:

首先编写代码并且不要费心询问性能直到遇到问题,在分析后明确指出此测试是问题。

我只想使用contains方法。但这是一种没有实际测试的意见。

答案 3 :(得分:2)

通过这个简单的例子你不应该看到很多性能差异,但纯粹来自算法涉及正则表达式

wordA|wordB
确实会更快,因为它只是通过字符串进行单次传递并使用有限自动机来匹配两个子串中的一个。然而,这首先被构建有限自动机所抵消,在这种情况下,它应该在正则表达式的长度上非常线性。只要编译对象存在,您就可以首先编译正则表达式,使其只有一次。

所以基本上成本归结为:

  • 线性搜索字符串两次(2·字符串长度
  • 线性搜索字符串一次并构建DFA(字符串长度 + 正则表达式

如果您的文字非常大且子字符串非常很小,那么这可能是值得的。

尽管如此,你最有可能优化错误的地方。使用分析器查找代码中的实际瓶颈并优化它们;除非你能证明它们能产生影响,否则不要担心这种微不足道的“优化”。

最后要考虑的是:使用正则表达式,你可以确保你实际上匹配单词(或看起来像单词的东西)而不是单词部分,这可能是考虑正则表达而不是{{{ 1}}。

答案 4 :(得分:2)

在我看来,这是一个品味问题。避免过早优化,请参阅Practical rules for premature optimization

  1. 作为一般规则,如果您要查找 子字符串而不是模式,请不要使用正则表达式

  2. 对于文本搜索这样一个简单的正则表达式只会有轻微的性能差异,所以如果你只是偶尔进行一次搜索而不是性能问题。如果你做了几千次或更多,在一个循环中,然后制作基准,如果你有性能问题