在另一个字符串中查找字符串出现的最快方法是什么?

时间:2011-04-28 15:55:45

标签: php string substring

  

可能重复:
  Which method is preferred strstr or strpos ?

嗨!

你能告诉我哪一个更快
strstr($mystring, $findme);
OR
strpos($mystring, $findme);
或者
别的什么

在另一个中找到 - 第一个或任何 - 出现的字符串

如果我使用stristr()stripos()来检查不区分大小写的模式,那么它在性能方面是否重要?

在我的情况下,给定字符串在哪个确切位置(如果有),或者在另一个字符串中发生了多少次(如果有的话)并不重要,唯一重要的问题是它是否存在于其他字符串。

我已经在各篇文章中找到了一些关于速度差异的评论(例如on php.net,有人说strstr()在strpos之后有一个!==错误检查的情况下更快,但现在我可以不确定哪个是真的。

如果您知道在其他方法中搜索字符串的更好方法,请告诉我们!

非常感谢您的相关评论!

============

一个例子:


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

if(strstr($mystring, $findme)){  
   echo 'got it';  
}  
else{  
   echo 'none';  
}  

echo PHP_EOL;

if(strpos($mystring, $findme) !== false){  
   echo 'got it';  
}  
else{  
   echo 'none';  
}  


7 个答案:

答案 0 :(得分:22)

strpos似乎处于领先地位,我在'The quick brown fox jumps over the lazy dog'找到了一些字符串进行了测试:

  • strstr使用0.48487210273743秒进行1000000次迭代查找'quick'
  • strpos使用0.40836095809937秒进行1000000次迭代查找'quick'
  • strstr使用0.45261287689209秒进行1000000次迭代查找'dog'
  • strpos使用0.39890813827515秒进行1000000次迭代查找'dog'
<?php

    $haystack = 'The quick brown fox jumps over the lazy dog';

    $needle = 'quick';

    $iter = 1000000;

    $start = microtime(true);
    for ($i = 0; $i < $iter; $i++) {
        strstr($haystack, $needle);
    }
    $duration = microtime(true) - $start;
    echo "<br/>strstr used $duration microseconds for $iter iterations finding 'quick' in 'The quick brown fox jumps over the lazy dog'";

    $start = microtime(true);
    for ($i = 0; $i < $iter; $i++) {
        strpos($haystack, $needle);
    }
    $duration = microtime(true) - $start;
    echo "<br/>strpos used $duration microseconds for $iter iterations finding 'quick' in 'The quick brown fox jumps over the lazy dog'";

    $needle = 'dog';

    $start = microtime(true);
    for ($i = 0; $i < $iter; $i++) {
        strstr($haystack, $needle);
    }
    $duration = microtime(true) - $start;
    echo "<br/>strstr used $duration microseconds for $iter iterations finding 'dog' in 'The quick brown fox jumps over the lazy dog'";

    $start = microtime(true);
    for ($i = 0; $i < $iter; $i++) {
        strpos($haystack, $needle);
    }
    $duration = microtime(true) - $start;
    echo "<br/>strpos used $duration microseconds for $iter iterations finding 'dog' in 'The quick brown fox jumps over the lazy dog'";

?>

答案 1 :(得分:15)

来自PHP Docs

  

注意:

     

如果您只想确定是否   特别针发生在   干草堆,使用越快越少   内存密集型函数strpos()   代替。

我愿意接受他们的话:)

答案 2 :(得分:6)

更快的方法是:

if (strpos($haystack, $needle) !== false)

不区分大小写的版本显然应该更慢(至少慢2倍,我期待)。


strncmp() / substr()可能会更好地 iff 您正在检查$haystack 是否已启动 $needle如果$haystack相当长(>大约数百个字符)。


基准:

请参阅其他基准@ http://net-beta.net/ubench/(搜索strpos)。


一种实际的例子,这种优化(种类)很重要 - calculating hashcashes

$count = 0;
$hashcash = sprintf('1:20:%u:%s::%u:', date('ymd'), $to, mt_rand());

while (strncmp('00000', sha1($hashcash . $count), 5) !== 0)
{
    ++$count;
}

$header['X-Hashcash'] = $hashcash . $count;

答案 3 :(得分:2)

根据php手册页,strpos比strstr更快,内存更少。

答案 4 :(得分:0)

欺骗问题。他们做了两件不同的事情。一个返回子字符串,另一个返回带有字符串的子字符串的起始位置。真正的答案是你将苹果与橙子进行比较,使用你需要的苹果。

答案 5 :(得分:0)

如果要查找模式B出现的字符串A,那么最快的方法是构建A的后缀树并对其执行搜索B.

答案 6 :(得分:0)

我认为strpos()会更快,因为它只返回一个整数(如果没有找到匹配,则返回false)。 strstr()返回一个字符串,其中包含第一个匹配项之后的所有文本。

对于不区分大小写的搜索,我认为这些会稍慢,因为它们必须执行额外的检查(“两个字符是否匹配?如果不是,char是字母吗?如果是,它是否与小写版本匹配?如果不是,它是否与大写版本匹配?“等等)