preg_replace速度优化

时间:2010-01-22 15:10:39

标签: php regex

在查看stripping out all characters from a string, leaving numbers的接受答案时,作者在表达式

之后添加了+
$str = preg_replace('/[^0-9.]+/', '', $str);

为了找到要删除的子字符串而不是单个字符串。对于功能,+是可选的。但我开始怀疑添加+是否更快。 (或者没有任何区别?)

由于较少的字符串和内存处理,我认为它更快。但我也能理解更复杂的正则表达式比简单表达式要慢。

因此,当使用此技术删除子字符串时,应该尝试查找大型或小型子字符串吗?

3 个答案:

答案 0 :(得分:1)

不要过多地阅读基准测试结果。他们很难做得很好。真的,你应该从中得到的唯一一点就是在某些类型的字符串上重复可能会更快,重复的范围很长。

这种类型的东西可以使用不同版本的PCRE轻松更改。


function tst($pat, $str) {
    $start = microtime(true);
    preg_replace($pat, '', $str);
    return microtime(true) - $start;
}
$strs = array(
    'letters' => str_repeat("a", 20000),
    'numbers' => str_repeat("1", 20000),
    'mostly_letters' => str_repeat("aaaaaaaaaaaaa5", 20000),
    'mostly_numbers' => str_repeat("5555555555555a", 20000)
);
$pats = array(
    'rep' => '/[^0-9.]+/',
    'norep' => '/[^0-9.]/'
);

//precompile patterns(php caches them per script) and warm up microtime
microtime(true);
preg_replace($pats['rep'], '', 'foo');
preg_replace($pats['norep'], '', 'foo');

foreach ($strs as $strname => $str) {
    echo "$strname\n";
    foreach ($pats as $patname => $pat) {
        printf("%10s    %.5f\n", $patname, tst($pat, $str));
    }
}

答案 1 :(得分:1)

我建议chris进行一些速度测试。与他的代码相比我:

  • 添加了一个str_replace进行比较:
$str_replace_array = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.');

function tst($pat, $str) {
    global $str_replace_array;
    $start = microtime(true);
    if($pat == '')
        str_replace($str_replace_array, '', $str);
    else
        preg_replace($pat, '', $str);
    return microtime(true) - $start;
}
  • 使所有字符串长度相同,因此可以更好地比较结果

结果:

letters
         rep    0.00298
       norep    0.06953
 str_replace    0.00406

numbers
         rep    0.02867
       norep    0.02612
 str_replace    0.01242

mostly_letters
         rep    0.00931
       norep    0.06649
 str_replace    0.00593

mostly_numbers
         rep    0.03285
       norep    0.02942
 str_replace    0.01359

它表明重复的正则表达式(添加了+)在替换较大的块时速度更快(内存处理量更少?)但是,当不需要更换时,没有重复的正则表达式会稍快一些。

此外,str_replace 基本上总是比正则表达式替换更快(速度的两倍),除非正则表达式与完整字符串匹配。

答案 2 :(得分:0)

我没有做过任何测试,但是+你匹配更多的字符,所以替换过程应该执行的次数少一些。如果你没有在正则表达式中编写+,则替换是在每个字符上完成而不是替换整个子字符串,所以我认为它更慢。