2

假设我有abcdeXqwerXiop(编辑:我们知道有 X)我想回来abcdeXqwer- 在最后一次出现时剪切字符串X(不包括最后一个字符)。最快的方法是什么?我最好的主意是

preg_replace('/.[^X]+$/', '', $string);
4

3 回答 3

0

最快的方法是完全跳过正则表达式:

substr($string, 0, strrpos($string, "X") + 1);
于 2013-08-07T02:34:57.057 回答
0

为什么是正则表达式?这会快得多。

substr($string, 0, strrpos($string, 'X'));
于 2013-08-07T02:35:06.653 回答
0

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 跟踪了这一点,结果是一致的。

于 2013-08-07T02:53:20.123 回答