哪种方法是首选strstr或strpos?


84

我注意到许多开发人员同时使用strstr和strpos来检查子字符串是否存在。是其中之一吗?为什么?


2
您提到的基准是与substr而非strstr
Flask,

Answers:


125

从PHP在线手册中

如果只想确定干草堆中是否发生了特定的刺针,请改用速度更快且占用较少内存的功能strpos()


13
+1,您可以使用strpos或stripos。并且不要忘记查看有关使用=== FALSE的php文档上的警告;
fedmich 2012年

7
详细阐述fedmich的评论:我总是使用if(strpos($haystack,$needle) !== false) { // do something },从不使用if(strpos($haystack,$needle)) { // do bad things }strpos如果的$needle开头是$haystack,则将返回0 ,并且0等于false。(0 == false)评估为true。(0 === false)评估为假。
Buttle Butkus 2014年

1
来自C的人们可能会考虑使用strchr函数,但是在PHP中,它实际上是strstr的别名,因此strpos是一个更好的选择。
e2-e4 2014年

38

是我对问题的其他答案(+基准),几乎是相同的(问时我没有意识到您的问题)。


在此期间,我还做了我自己的基准测试,我跑了100万倍每个相关的功能(strstr()strpos()stristr()stripos())。
这是代码:

<?php

function getmicrotime() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float) $usec + (float) $sec);
}

$mystring = 'blahblahblah';  
$findme = 'bla';  

echo 'strstr & strpos TEST:<pre>';
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) strstr($mystring, $findme);
$time_needed_strstr = getmicrotime() - $time_start;
echo 'strstr():            ',
    round( $time_needed_strstr , 8 ). PHP_EOL;

$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) stristr($mystring, $findme);
$time_needed_stristr = getmicrotime() - $time_start;
echo 'stristr():           ',
    round( $time_needed_stristr , 8 ) . PHP_EOL;

$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) strpos($mystring, $findme) !== false;
$time_needed_strpos = getmicrotime() - $time_start;
echo 'strpos() !== false:  ',
    round( $time_needed_strpos , 8 ) . PHP_EOL;

$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) stripos($mystring, $findme) !== false;
$time_needed_stripos = getmicrotime() - $time_start;
echo 'stripos() !== false: ',
    round( $time_needed_stripos , 8 ) . PHP_EOL;

echo PHP_EOL;

echo 'time_needed_stristr - time_needed_strstr: ',
     round( $time_needed_stristr - $time_needed_strstr , 8) . PHP_EOL;
echo 'time_needed_stripos - time_needed_strpos: ',
     round( $time_needed_stripos - $time_needed_strpos , 8) . PHP_EOL;

echo PHP_EOL;

echo 'time_needed_strstr  - time_needed_strpos:  ',
     round( $time_needed_strstr - $time_needed_strpos , 8) . PHP_EOL;
echo 'time_needed_stristr - time_needed_stripos: ',
     round( $time_needed_stristr - $time_needed_stripos , 8) . PHP_EOL;

echo '</pre>';

?>

这是第一个输出,显示出strpos()获胜者

strstr & strpos TEST:
strstr():            2.39144707
stristr():           3.65685797
strpos() !== false:  2.39055395
stripos() !== false: 3.54681897

time_needed_stristr - time_needed_strstr: 1.2654109
time_needed_stripos - time_needed_strpos: 1.15626502

time_needed_strstr  - time_needed_strpos:  0.00089312
time_needed_stristr - time_needed_stripos: 0.110039 

下一个类似于第一个输出(strpos()再次是获胜者):

strstr & strpos TEST:
strstr():            2.39969015
stristr():           3.60772395
strpos() !== false:  2.38610101
stripos() !== false: 3.34951186

time_needed_stristr - time_needed_strstr: 1.2080338
time_needed_stripos - time_needed_strpos: 0.96341085

time_needed_strstr  - time_needed_strpos:  0.01358914
time_needed_stristr - time_needed_stripos: 0.25821209

下面是另一个,更有趣,因为在这种情况下strstr()是获胜者:

strstr & strpos TEST:
strstr():            2.35499191
stristr():           3.60589004
strpos() !== false:  2.37646604
stripos() !== false: 3.51773095

time_needed_stristr - time_needed_strstr: 1.25089812
time_needed_stripos - time_needed_strpos: 1.14126492

time_needed_strstr  - time_needed_strpos:  -0.02147412
time_needed_stristr - time_needed_stripos: 0.08815908

这意味着它确实可以依赖于有时很难影响的“环境”,并且可以更改“微优化任务”的结果,以防您只是检查一个字符串是否存在于另一个字符串中。

但我认为在大多数情况下,strpos()相比是赢家strstr()

我希望这个测试对某人有用。


3
尽管此基准很有用,但它不衡量内存消耗,也没有考虑长字符串,例如千字节或兆字节。

??@ user133408长字符串和大字节字符串甚至需要更长的时间。
NiCk Newman

7

许多开发人员将其strpos用于微优化目的。

strstr仅当在布尔上下文中不能将结果字符串解释为false时,使用也才有效。


11
这不是微观优化,而是为工作使用正确的功能。如果需要字符串的位置,请致电strpos()。如果需要该位置后的子字符串,请致电strstr()
Alnitak

1
@Alnitak:我说的是。如果您要检查字符串是否存在,那么可以使用一个函数。如果您确实需要该职位,那么还有一个职位。-当您探查该职位而不实际需要该职位时,这几乎就不是“使用正确的功能来完成工作”。这样做的目的显然是优化微秒。(这不是您引用的内容吗?)
mario

1
@mario,但是没有函数的唯一目的是检查子字符串是否存在。实际找到子字符串的位置(如果找到)是免费的信息。OTOH,strstr比是必需的,这就是为什么它的速度较慢。
Alnitak

@Alnitak:提醒你,不是新闻。您似乎非常坚决指出性能差异,仅此而已。这是微优化的明显标志。它不会在探查器中引起意外。确实有所不同的地方在于代码的可读性。
mario

@mario实际上我只在乎性能。我非常在意为工作使用正确的功能;-)
Alnitak

0

strpos()检测特定针头在大海捞针中的位置。stristr()测试针是否在干草堆中的任何位置

因此strpos()更快,内存消耗更少

使用strstr()的原因:如果您的指针位于字符串的开头,则strpos返回0(因此必须使用=== false进行检查)


6
这是一个完全伪造的解释-strstr()返回在指针之前或之后的所有内容,因此它首先必须执行等效操作,strpos() 然后创建该子字符串。那就是性能受到冲击的地方。
Alnitak

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.