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

Java 使用正则表达式的性能开销/改进,java,regex,string,performance,full-text-search,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两次更好 您的

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

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

是否使用某个正则表达式搜索字符串?
它是否依赖于正则表达式格式?
还是只是口味的问题

更新:
如果
text.contains(wordA)
false
,则将计算
text.contains(wordB)

这意味着
contains
将被调用两次


我在想,就性能而言,正则表达式是否比调用
contains
两次更好

您的代码清楚地表达了您的意图,比regexp更具可读性,而且可能更快


无论如何,这部分代码导致任何重大性能问题的可能性很低。因此,我不会在这里担心性能,而是担心可读性和可维护性。

通过这个简单的示例,您不应该看到太多的性能差异,但纯粹是因为正则表达式所涉及的算法

wordA|wordB
它的速度确实更快,因为它只通过字符串进行一次遍历,并使用有限自动机匹配两个子字符串中的一个子字符串。然而,首先构建有限自动机可以抵消这一点,在本例中,有限自动机在正则表达式的长度上应该是非常线性的。您可以先编译正则表达式,这样只要编译对象存在,就只需要花费一次时间

因此,成本基本上归结为:

  • 对字符串进行两次线性搜索(2·字符串长度)
  • 线性搜索字符串一次并构建DFA(字符串长度+正则表达式长度)
如果文本非常大,子字符串非常小,那么这可能是值得的

不过,很可能你优化了错误的位置。使用分析器找出代码中的实际瓶颈,并对其进行优化;永远不要担心这些琐碎的“优化”,除非你能证明它们会产生影响


最后一件事要考虑的是:用正则表达式可以确保你实际上是匹配单词(或者看起来像单词的事物)而不是单词部分,这可能是考虑正则表达式而不是<>代码包含的实际原因。

< P>是的,它们是有区别的。Contains执行各种数组操作来查找单词,正则表达式使用不同的逻辑,因此它会有所不同,性能甚至会根据使用正则表达式匹配的方式而变化

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

首先编写代码,在分析清楚地表明此测试是问题所在之后,在遇到问题之前不要质疑性能


我只会使用contains方法。但这是一个没有实际测试任何东西的观点。

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

  • 作为一般规则,如果要查找单词子字符串而不是模式,则不要使用正则表达式

  • 这样一个简单的正则表达式与文本搜索的性能差别很小,因此,如果您偶尔只进行一次搜索,则不会出现性能问题。如果您在一个循环中执行了上千次或更多次,那么,如果您有性能问题,请制定一个基准


  • 虽然正则表达式的性能较低,但它的表达能力更强,这一点通常更为重要。比如说

     "performance".contains("form") // is true
    
    这可能不是你想要的一个“词”,相反,你可以有一个模式

     "\\bform\\b"
    

    这将只匹配字符串中的完整单词,可以在开头或结尾。

    我理解你的意思。我担心
    包含(a)
    包含(b)
    将解析两次,例如正则表达式可以在一次解析中完成。您认为这可能是一个问题吗?您所说的两次解析是什么意思?如果text.contains(wordA)返回true,第二个表达式将永远不会被计算。@quaylar:如果
    text.contains(wordA)
    false
    则第二个表达式将被计算。我认为使用正则表达式会比调用
    contains
    两次更快。stema:关于规则1,这是一个标准的方法还是你的建议?我对你的规则感兴趣。我认为它是一个标准的方法,正则表达式是一个优秀的、强大的模式匹配工具,我不认为一个固定的单词是一种模式。一旦这个词有变化或者必须在某个地方,它看起来就不一样了。所以,只有当我搜索<代码> Worda <代码>时,你才会提出这个建议。如果我考虑一个匹配,也就是代码> Word Worda < /Cord>你的建议仍然适用。@ USSR84706我在我的规则1中改变了一个单词。Peter Lawrey的回答提醒我,一个词已经是一种模式,如果这个词包含在另一个词中,通常不应该找到它(取决于您的要求)。如果您的数据来自磁盘,I/O开销将完全支配您的测量,编译正则表达式和扫描缓冲区两次的成本将减少到测量误差范围内。