【问题标题】:Which method is preferred strstr or strpos?哪种方法是首选 strstr 或 strpos?
【发布时间】:2011-04-28 14:53:36
【问题描述】:

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

【问题讨论】:

  • 你提到的基准是与 substr 而不是 strstr

标签: php strpos strstr


【解决方案1】:

来自 PHP online manual:

如果你只想确定一个 特定的针发生在 干草堆,用得越快越少 内存密集型函数strpos() 而是。

【讨论】:

  • +1,您可以使用 strpos 或 stripos。并且不要忘记检查 php 文档上关于使用 === FALSE; 的警告
  • 详细说明 fedmich 的评论:我总是使用 if(strpos($haystack,$needle) !== false) { // do something },从不使用 if(strpos($haystack,$needle)) { // do bad things }。如果$needle 位于$haystack 的最开头,strpos 将返回 0,并且 0 被认为等于 false。 (0 == false) 评估为真。 (0 === false) 计算结果为假。
  • 来自 C 的人可能会考虑使用 strchr 函数,但在 PHP 中它实际上是 strstr 的别名,所以 strpos 是更好的选择。
【解决方案2】:

Here 是其他一些答案(+基准)我得到了我的问题,这几乎相同(我在询问时没有意识到你的问题)。


与此同时,我还进行了自己的基准测试,针对每个相关功能(strstr()、strpos()、stristr() 和 stripos())运行了 1000000 次。
代码如下:

<?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() 相比是赢家。

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

【讨论】:

  • 虽然这个基准测试很有用,但它不会测量内存消耗,也不会考虑长字符串,例如 kbytes 或 mbytes。
  • 嗯? @user133408 长字符串和更大的字节字符串甚至需要更长的时间。
【解决方案3】:

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

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

【讨论】:

  • 这不是微优化,它被称为为工作使用正确的功能。如果我想要字符串的位置,我调用strpos()。如果我想要那个位置之后的子字符串,我打电话给strstr()。
  • @Alnitak:我在说什么。如果你想检查一个字符串是否存在,那么有一个函数可以做到这一点。如果你确实需要这个职位,那么还有另一个。 ——当你在实际上不需要职位的情况下寻找职位时,那几乎不是“为工作使用正确的功能”。其目的显然是优化微秒。 (这不是你引用的吗?)
  • @mario 但没有唯一目的是检查子字符串是否存在的函数。子字符串的 position (如果找到)是您实际找到后的免费信息。 OTOH,strstr 比要求的更多,这就是它变慢的原因。
  • @Alnitak:请注意,不是新闻。您似乎非常坚持指出性能差异,仅此而已。这是微优化的一个典型标志。 它不会在探查器中产生信号。它确实有所作为的地方在于代码的可读性。
  • @mario 实际上我只关心性能。我非常关心为工作使用正确的功能;-)
【解决方案4】:

strpos() 检测特定针在大海捞针的位置。 stristr() 测试针是否在大海捞针中的任何地方

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

strstr() 的一个原因:如果你的 needle 位于字符串的开头,strpos 返回 0(所以必须用 === false 进行检查)

【讨论】:

  • 这是一个完全虚假的解释 - strstr() 返回针之前或之后的所有内容,因此它首先必须执行与 strpos() 等效的操作然后创建该子字符串。这就是性能受到影响的地方。
【解决方案5】:

我更喜欢 strstr() 因为可读性和易于编码.. strpos() !==false 有点混乱..

【讨论】:

  • strstr 与strtr 过于相似
  • strstr 也需要严格比较 例如:('123450', '0')
猜你喜欢
  • 1970-01-01
  • 2017-12-17
  • 1970-01-01
  • 2021-08-04
  • 2012-08-23
  • 1970-01-01
  • 2020-06-04
  • 2010-10-03
  • 2021-12-10
相关资源
最近更新 更多