假设我有abcdeXqwerXiop
(编辑:我们知道有 X)我想回来abcdeXqwer
- 在最后一次出现时剪切字符串X
(不包括最后一个字符)。最快的方法是什么?我最好的主意是
preg_replace('/.[^X]+$/', '', $string);
最快的方法是完全跳过正则表达式:
substr($string, 0, strrpos($string, "X") + 1);
为什么是正则表达式?这会快得多。
substr($string, 0, strrpos($string, 'X'));
tl;dr:我并不像我想象的那样了解微优化——但没有人愿意提供证据。
没有提供两个函数调用是否比一个更快的证据。所以,这是一个脚本:
$string = str_repeat('abcdeXqwerXiopreyX', 50) . 'aaaaaaa';
function test($string) {
for ($i = 0; $i < 10000; $i++) preg_replace('/X[^X]+$/', '', $string);
}
function test1($string) {
for ($i = 0; $i < 10000; $i++) substr($string, 0, strrpos($string, 'X') + 1);
}
test($string);
test1($string);
然后我跑去php -d xdebug.auto_trace=1 test.php
发现脚本test()
在 0.0004 处输入test1()
,在 0.683 处输入 0.3430。所以test()
需要 0.3426 而test1()
需要 0.2652。
我们可以同意这两个调用确实更快。
但是,如果我们想坚持正则表达式,则提供了 `X[^X]+$' 更快但没有证据。我找到了调试它们的方法。PHP 不能,但 Perl 可以。
所以,
$string = 'abcdeXqwerXiop';
$string =~ s/X[^X]+$//;
print $string;
然后运行perl -Mre=debug test.pl
。在这里粘贴太长了,但是这个脚本的输出是 27 行长,而.[^X]+$
确实需要 75 行,是找到匹配项的几倍。
编辑:这可能是不正确的,因为 PCRE 和 Perl 是不同的实现,可能有不同的优化,但我也用 xdebug 跟踪了这一点,结果是一致的。