2010-01-22 203 views
2

当在stripping out all characters from a string, leaving numbers接受的答案来看,笔者为了找到子串表达的preg_replace速度优化

$str = preg_replace('/[^0-9.]+/', '', $str); 

后添加一个+,而不是单一的事件,以去除。对于功能+是可选的。但我开始怀疑加入+是否更快。 (或没有任何区别?)

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

所以当使用这种技术来删除子字符串应该试图找到大或小的子字符串?

+0

这不符合*完整*正则表达式 – SilentGhost 2010-01-22 15:13:38

+1

找出方法:测试它。试试这三个表达式,并在相当大的一组字符上测试它们:'[^ 0-9。]','[^ 0-9。] +'和'[^ 0-9。] ++'。 – 2010-01-22 15:14:20

+0

@SilentGhost:我没有说它很复杂(当然不是),我说*更复杂*。 – Veger 2010-01-22 15:29:23

回答

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)); 
    } 
} 

+0

噢,我很快就会测试它(当我有机会的时候)。也许增加str_replace(数组(“0”,...,“9”,“。”)。“),'',$ str)以及... :) – Veger 2010-01-22 19:28:28

0

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

+0

这就是我的想法,但正则表达式呢?添加+时(慢)是多少?如果是这样的话,由于更少的amtches,它与更高的更换速度相比如何? – Veger 2010-01-22 15:28:31

+0

我不知道这一点,但我认为在相同的比赛中匹配更多的字符不会影响正则表达式的性能。 – mck89 2010-01-22 15:35:25

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 基本上总是更快(速度的两倍)比正则表达式替换,除非正则表达式匹配整个字符串。