解析许多小字符串或单个大字符串 - 哪个更快?

时间:2012-12-24 03:52:05

标签: regex performance

在必须使用正则表达式解析大量字符串的情况下,考虑使用相同的RegEx指针将用于所有测试,这将更快:

  1. 单独测试数组中的每个字符串,或者;
  2. 将所有内容连接成一个大字符串并只测试一次?
  3. 我认为数字2是最好的,而不是必须多次启动RegEx引擎来处理字符串数组。但是,经过PHP(PCRE)的一些测试后,它似乎是不真实的。

    基准


    我在PHP 5.3 (source code)中做了一个简单的基准测试,得到了以下结果:

      

    122185 在5秒内测试数组内多个较小的字符串

         

    26853 5秒内进行单项大字符串测试的交互

    因此,我必须得出结论,第一种方法的速度提高了5倍。但是,我想要一个确认这一点的权威答案;由于我不知道的一些PHP优化,我可能会错误地假设。

    在使用正则表达式测试大型字符串之前,它是否总是更优化的解决方案,而不是特别是在PCRE中?

    preg_grep()

    我不认为这里应该考虑这个功能。这是一个基准测试,而不是优化问题。更不用说该函数是特定于PHP的方法。此外,preg_match_all返回所有匹配的子字符串,而preg_grep仅指示匹配的数组元素。

2 个答案:

答案 0 :(得分:3)

您的基准存在缺陷。看看这段代码:

while(time() - $TimeStart < 5)
    for($i = 0; $i < $Length; $i++, $Iterations++)
    {
        preg_match_all($RegEx, $Input[$i], $m);
    }
}

$Iterations只应在<{1}}中增加 ,而不是在while内。除以前结果导致:

for

您不应该使用24437 iterations using array 26853 iterations using big string 进行时间测量,time()更适合提高准确度。

最后,此基准测试尚未完成,因为要为两个测试获得相同的结果,数组方法需要在每次迭代后执行microtime()。此外,某个地方需要将大字符串转换为数组,这也需要时间。

答案 1 :(得分:1)

你绝对应该将所有目标字符串合并为一个。首先,它会打破很多正则表达式,在较短的字符串上工作正常。像^$\A\z这样的主播会突然发现自己无法匹敌。此外,严重依赖于.* or。*?`的正则表达式,尽管它们固有的低效率,它们在较短的字符串上工作,但在用于Frankenstring时会变得catastrophically慢。

但即使连接版本更快,重要吗?您是否尝试过阵列版本并发现它太慢了?这是一个非常激烈的解决方案(如果是解决方案);如果我是你的话,我会推迟实施它,直到我遇到问题为止。