我用 PHP 编码已经有一段时间了,我一直在读到你应该只在必须使用preg_match
的preg_replace
时候使用,因为它会降低性能。为什么是这样?preg_matches
在一个文件中使用 20 而不是使用另一个 PHP 函数真的很糟糕吗?
6 回答
正如 Mike Brant 在他的回答中所说:如果需要,使用任何preg_*
功能都没有错。
您想知道在一个文件中包含 20 个调用是否是个好主意,好吧,老实说:我会说这太多了。我经常说“如果您对问题的解决方案在任何给定时间都依赖于 3 个以上的正则表达式,那么您就是问题的一部分”。不过,我偶尔也会违背自己的咒语。preg_match
如果您使用20preg_match
次调用,则只需仔细查看实际的正则表达式,您就可以将这个数字减半。正则表达式,尤其是 Perl 正则表达式,非常强大,非常值得花时间去了解它们。它们趋于变慢的原因仅仅是因为必须解析正则表达式,并将其“翻译”成相当数量的低级分支和循环。a
比如说,如果你想用大写字符替换所有小写字母,你可以使用正则表达式,当然,但在 PHP 中,这看起来像这样:
preg_replace('/a/','A',$string);
查看表达式,第一个参数:它是作为参数传递的字符串。该字符串将被解析(解析时,检查分隔符,创建匹配字符串然后迭代字符串,将每个字符与模式进行比较(在这种情况下a
),如果子字符串匹配,则将其替换。
看起来像有点麻烦,特别是考虑到最后一步(比较子字符串和替换匹配)是我们真正想要的。
$string = str_replace('a','A',$string);
这样做,无需在解析和验证正则表达式时执行额外的检查。
不要忘记它preg_match
也构造了一个匹配数组,构造一个数组也不是免费的。
简而言之:正则表达式的速度较慢,因为表达式被解析、验证并最终转换为一组简单的低级指令。
请注意,在某些情况下,人们使用explode
andimplode
进行字符串操作。这也创建了一个 - 再次 - 不是免费的数组。考虑到您此后不久就会内爆相同的数组。也许另一种选择更可取(在某些情况下preg_replace
可以更快)。
基本上:正则表达式需要额外的处理,简单的字符串函数不需要。但是当有疑问时,只有一种方法可以绝对确定:设置一个测试脚本......
除非遇到问题,否则不要担心优化。
不要在没有使用 XDebug (http://xdebug.org) 之类的工具进行测量的情况下寻找优化区域。
如果您的代码使用 preg_match() 运行需要 100 毫秒,而通过其他方法需要 110 毫秒,那么您真的关心差异吗?
先写正确和清晰,然后考虑速度。
这实际上取决于您的用例。使用正则表达式本身并没有什么“坏处”。有时它是您对特定问题的唯一可用解决方案。但是,有时简单的字符串操作函数也可以正常工作。这些往往比preg*
函数更快,因此,如果您遇到脚本运行非常频繁和/或要执行大量字符串操作的情况,则可以开始感受到使用正则表达式的影响。
与任何情况一样,您应该在您的应用程序和环境中进行测试并确定最适合您的方法。
检查它需要多少时间(显示时间STARTED和ENDED):
var_dump( microtime(true) );
//............... your function executions here.............
var_dump( microtime(true) );
取决于你在做什么。对于复杂的正则表达式,只需使用 preg_ 函数,如果您需要简单的替换或类似函数,请使用其他更具体的函数,如 str_replace()、strpos()、strstr()...
网络上到处都是讨论,比如http://www.simplemachines.org/community/index.php?topic=175031.0
对于短字符串(例如小于几千字节),性能差异可以忽略不计。对于长字符串,例如超过 30-50 kB(通常是所见即所得的内容),性能差异变得更加显着,特别是对于贪婪的变体 - 例如preg_match_all
。因此,对于长字符串,使用简单的字符串迭代/查找通常会更快,例如通过str_pos()
提取或替换部分字符串,substr()
然后只应用 preg_* 函数 - 对于提取的短字符串。