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

问题描述 投票:0回答:2

在需要用正则表达式解析大量字符串的场景下,考虑到所有测试都会使用同一个RegEx针,这样会更快:

  1. 单独测试数组中的每个字符串,或者;
  2. 将所有内容连接成一个大字符串并仅测试一次?

我相信第 2 种方法是最好的,而不必多次启动 RegEx 引擎来处理字符串数组。然而,在 PHP (PCRE) 中进行一些测试后,这似乎不正确。

基准


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

122185 5 秒内进行交互测试数组内的多个较小字符串

26853 5 秒内进行单大串测试交互

因此,我必须得出结论,第一种方法最多快 5 倍。不过,我想请求一个权威的答案来证实这一点;由于我不知道的一些 PHP 优化,我可能会错误地假设事情。

在使用正则表达式测试大字符串之前对大字符串进行分段是否总是一种更优化的解决方案,而不是专门在 PCRE 中?

preg_grep()

我认为这里不应该考虑这个功能。这是基准测试,而不是优化问题。更不用说该函数是 PHP 特有的方法。此外,

preg_match_all
返回所有匹配的子字符串,而
preg_grep
仅指示哪些数组元素匹配。

php regex performance
2个回答
3
投票

您的基准有缺陷。看看你的这段代码:

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

$Iterations
应该仅在while
 中增加,而不是在
for
 内部增加。将前面的结果除以:

24437 iterations using array 26853 iterations using big string

您不应该使用

time()

 进行时间测量,
microtime()
 更适合获得准确性。

最后,这个基准测试并不完整,因为为了获得两次测试相同的结果,数组方法需要在每次迭代后执行

array_merge()

。另外,某个地方需要将大字符串转换为数组,这也需要时间。


1
投票
您绝对不应该

将所有目标字符串合并为一个。一方面,它会破坏许多在较短字符串上正常工作的正则表达式。像^

$
\A
\z
这样的锚点会突然发现自己没有任何匹配的东西。此外,严重依赖诸如
.* or
.*?` 之类的正则表达式,尽管其固有的低效率,但在较短的字符串上工作,当在弗兰肯字符串上使用时,往往会变得“灾难性的”缓慢。

但即使串联版本更快,这有关系吗?您是否尝试过阵列版本并发现它太慢?这是一个非常彻底的解决方案(如果是的话);如果我是你,我会推迟实施它,直到我有一个可以解决的问题为止。

© www.soinside.com 2019 - 2024. All rights reserved.