What is the fastest way to find the occurrence of a string in another string? [duplicate]
Asked Answered
R

7

8

Possible Duplicate:
Which method is preferred strstr or strpos ?

Hi!

Could you tell me which one is faster:
strstr($mystring, $findme);
OR
strpos($mystring, $findme);
OR
anything else

in finding the - first or any - occurrence of a string in another one?

Does it even matter in performance if I check the occurrence in a case-insensitive mode with stristr() OR stripos()?

In my case it doesn't matter in which exact position the given string is (if any), or how many times it occurs in the other one (if any), the only important question is if it even exists in the other string.

I've already found some comments about differences of speed in various articles (e.g. on php.net, someone says strstr() is faster in case there is a !== false check after strpos), but now I can't decide which is true.

If you know about any better methods of searching a string in another, please let me know!

Thank you very much for the relevant comments!

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

An example:


$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';  
}  


Reinke answered 28/4, 2011 at 15:55 Comment(5)
This is a micro micro optimization in my opinion. But I'm curious the answer ;)Roadbed
This was asked (again) less than one hour ago...Grafton
Execute them 10.000 times and measure time before and after, you'll know which one is faster.Lanctot
Alix, you're right, I'm sorry for that, I didn't find this one. Capsule: this was a good idea, in the meantime I already made a test, I will post it soon.Reinke
aw, didn't think I get a downvote for being a little bit inattentive :((Reinke
I
23

strpos seems to be in the lead, I've tested it with finding some strings in 'The quick brown fox jumps over the lazy dog':

  • strstr used 0.48487210273743 seconds for 1000000 iterations finding 'quick'
  • strpos used 0.40836095809937 seconds for 1000000 iterations finding 'quick'
  • strstr used 0.45261287689209 seconds for 1000000 iterations finding 'dog'
  • strpos used 0.39890813827515 seconds for 1000000 iterations finding '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'";

?>
Impossibly answered 28/4, 2011 at 16:13 Comment(3)
Nice job, I believe this bench already was @ phpbench.com (if only it was up)!Grafton
Another one: net-beta.net/ubench/index.php?t=strpos1.Grafton
thanks for the benchmark, in the meantime I also made mine: bit.ly/mDE7sL .Reinke
R
16

From the PHP Docs:

Note:

If you only want to determine if a particular needle occurs within haystack, use the faster and less memory intensive function strpos() instead.

I'm willing to take their word for it :)

Roadbed answered 28/4, 2011 at 16:0 Comment(5)
Finally a real answer with sources and proofs.Endomorph
@Matthieu, I assume you're being facetious.Roadbed
@Matthieu There is no "source and proof" there. "Proof" would be a real-live benchmark with expected input and usage that could be repeatedly run.Calathus
wow, thank you, I didn't notice this official info, while it was in front of my eyes, I just would have to open them :D:DReinke
@Jason @pst : Ok I got too excited... Maybe not prooved, but if the php doc says so... They know what they are talking about.Endomorph
G
6

The faster way is:

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

The case insensitive versions should obviouslly be slower (at least 2x slower, I expect).


strncmp() / substr() can possibly perform better iff you're checking if $haystack starts with $needle and if $haystack is considerably long (> hundreds chars or so).


Benchmark:

See other benchmarks @ http://net-beta.net/ubench/ (search for strpos).


A pratical example where this kind of optimizations (kind of) do matter - 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;
Grafton answered 28/4, 2011 at 16:0 Comment(7)
you find out the duplicate and answered as well. Do not think both are different things?Cuculiform
@Shakti Singh: No, because this one has another detail (the case insensitivity).Grafton
In this case you must remove your comment or answer otherwise it is creating confusion for some personsCuculiform
@Shakti Singh: I don't have to do anything, the comment is automatic FYI and the main question is exactly the same - I don't see a reason not to close it.Grafton
As your wish I thought it should beCuculiform
wow, thanks, it shows that strncmp() is really faster :) I voted it up, I still have to decide which answer to accept :DReinke
@Sk8erPeter: No problem, you have to keep in mind that strncmp() is not generally faster - only if at least one of the conditions I mentioned is met - strpos() on the other hand is generally faster than any of the alternatives. Either way we are talking about micro optimizations here, it shouldn't matter more than the combined time of all answerers (unless you're doing this like a zillion times or so). :PGrafton
W
2

According to the php manpages, strpos is faster and less memory intensive than strstr.

Warfold answered 28/4, 2011 at 16:4 Comment(0)
M
0

Trick question. They do two different things. One returns the substring, the other returns the starting position of the substring withing the string. The real answer is you are comparing apples to oranges, use which one you need.

Meryl answered 28/4, 2011 at 16:1 Comment(8)
+1 The only answer thus far that doesn't focus on a u-optimization.Calathus
The question ain't tricky: fastest way to find the occurrence of a string in another string.Grafton
@Alix Axel And it's ... still a trick question. This can't be answered without a performance analysis as the expected input must be considered (string and match position). The best is to say "use the correct function".Calathus
@Crayon Violent: I still disagree, strstr() internally is the same as substr() + strpos() so it will always be slower (and consume more memory since it returns a string). Either way, the "correct function" for the OP question is str[i]pos().Grafton
It's interesting that in the meantime I tried my own benchmark many times (I will post it), and I had to find out it's not calculable and/or certain that strstr is always slower. For example my last test's result: strstr(): 1.17782998, strpos() !== false: 1.191504, which means strstr was 0.01367402 faster... Hmmm. So maybe it depends.Reinke
@Crayon Violent: I don't really think it's like comparison of apples to oranges. I just asked for the FASTEST method to find the occurrence of a string in the other one, as Alix already said. As I layed it down in the beginning, I don't care about the exact position or the substring of the string, I was just curious about performance questions when finding something.Reinke
@Sk8erPeter: Because your computer is not always as fast as the previous millisecond. ;) Good benchmarking is an art and the only way to be sure is to go back in time and start the other test at the exactly same tick as the previous one - which, of course, is impossible. The other (possible) alternative is to study the algorithmic complexity of each function, and, as you may guess from all the answers, this seems to favor strpos().Grafton
@Alix Axel: yes, that's right. :)Reinke
N
0

If the string A against which you want to find an occurrence of a pattern B, then the fastest way is to build a Suffix Tree of A and perform against it searches for B.

Novanovaculite answered 28/4, 2011 at 16:3 Comment(1)
Could you explain a little bit better what you exactly mean?Reinke
C
0

I would think that strpos() would be faster because it only returns an integer (or false if no match was found). strstr() returns a string which contains all text after and including the first match.

For case insensitive searches, I would think that these would be slightly slower because they have to perform extra checks ("do the two chars match? if no, is the char a letter? if yes, does it match the lowercase version? if no, does it match the upper case version?", etc)

Corycorybant answered 28/4, 2011 at 16:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.