在进行单值检查时,哪种方法更好,为什么?
$string == 'The quick brown fox jumps over the lazy dog';
if(strpos($string, 'fox') !== false){
// do the routine
}
# versus
if(preg_match('/fox/i', $string)){
// do the routine
}
在进行单值检查时,哪种方法更好,为什么?
$string == 'The quick brown fox jumps over the lazy dog';
if(strpos($string, 'fox') !== false){
// do the routine
}
# versus
if(preg_match('/fox/i', $string)){
// do the routine
}
我更倾向于使用 strpos
而不是 preg_match
,因为正则表达式通常执行起来更耗费资源。
根据 preg_match
的官方 php 文档:
如果您只想检查一个字符串是否包含在另一个字符串中,请勿使用
preg_match()
。相反,使用strpos()
或strstr()
,因为它们会更快。
preg_match();
的文档里有一个很重要的提示,但像往常一样,我没有注意到。好吧,感谢你把它复制粘贴到这里。我想这就是PHP团队亲自回答了我的问题。 - tomsseisums当你不确定的时候,请进行基准测试!
显然,我们可以想出比这更好的基准测试,但是只是为了证明一点:随着规模的增长,strpos()
将会快得多。(这里快了近2倍)
编辑 我后来注意到正则表达式是不区分大小写的。再次使用 stripos()
进行公平比较后,结果是 11 比 15,因此差距变小了,但 preg_match()
仍然慢得多。
$str = "the quick brown fox";
$start1 = time();
for ($i = 0; $i<10000000; $i++)
{
if (strpos($str, 'fox') !== false)
{
//
}
}
$end1 = time();
echo $end1 - $start1 . "\n";
$start2 = time();
for ($i = 0; $i<10000000; $i++)
{
if (preg_match('/fox/i', $str))
{
//
}
}
$end2 = time();
echo $end2 - $start2;
// Results:
strpos() = 8sec
preg_match() = 15sec
// Results both case-insensitive (stripos()):
stripos() = 11sec
preg_match() = 15sec
函数a
比函数b
快,反之亦然。更不用说依赖于time
或microtime
是有问题的,它使用可能会变化的内部时钟。相反,我会使用[xdebug](http://xdebug.org/)。 - machineaddict除非绝对必要,否则不要使用正则表达式。在像这样的字符串上启动和部署正则表达式引擎所涉及的开销类似于使用大锤而不是普通的锤子,使用钻头而不是螺丝刀。
使用正则表达式还存在更大的错误率——不匹配的字符串、意外的结果等等。除非strpos不够灵活,否则请坚持使用它。
strcontains()
函数会更好。然而,我发现 strpos(...) !== false
和 preg_match('...', $string)
这两个构造都同样丑陋。 - user456814好的代码更加重要
因此,如果您认为这种事情很重要,请记住它是Big O中的常数。换句话说,数据库调用、On2或更糟糕的活动是唯一重要的事情。在大多数情况下,花费时间担心这些低级命令是徒劳无功的。
并不是暗示应该忽略常数;例如,我重构了收集图像的代码,因为它一次只能收集一个图像,每个图像需要1秒钟,使用多curl请求将持续时间从12秒降至1秒。这个想法是内置命令是低级别的,而代码结构更加关键。
下面的代码进行了1000万次低级调用,你会发现“节省”非常微不足道。
function prof_flag($str)
{
global $prof_timing, $prof_names;
$prof_timing[] = microtime(true);
$prof_names[] = $str;
}
function prof_print()
{
global $prof_timing, $prof_names;
$size = count($prof_timing);
for($i=0;$i<$size - 1; $i++)
{
echo "<b>{$prof_names[$i]}</b><br>";
echo sprintf(" %f<br>", $prof_timing[$i+1]-$prof_timing[$i]);
}
echo "<b>{$prof_names[$size-1]}</b><br>";
}
$l = 10000000;
$str = "the quick brown fox";
echo "<h3>Ran " .number_format($l,2) ." calls per command </h3>";
prof_flag("Start: stripos");
for ($i = 0; $i<$l; $i++)
if (stripos($str, 'fox') !== false) {}
prof_flag("Start: preg_match");
for ($i = 0; $i<$l; $i++)
if (preg_match('#fox#i', $str) === 1) {}
prof_flag("Finished");
prof_print();
这段代码的唯一价值在于它展示了一个酷炫的记录运行时间的方法。
Ran 10,000,000.00 calls per command
Start: stripos
2.217225
Start: preg_match
3.788667
Start: ==
0.511315
Start: ucwords lol
2.112984
Finished
您可以通过编写以下代码来优化上述的preg_match
:
preg_match('/(?>fox)/', $str)
这应该更快。
strstr
函数通常可以避免多余的结果检查。 - mariostripos
来使得它们的功能一样。 - Wesley Murch