どの方法が好ましいstrstrまたはstrposですか?


84

多くの開発者がstrstrとstrposの両方を使用して部分文字列の存在を確認していることに気付きました。それらの1つが好まれますか、そしてその理由は何ですか?


2
あなたが言及したベンチマークは、strstrではなくsubstrに対してです
Flask

回答:


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場合は0を返し、0はfalseに等しいと見なされます。trueと評価されます。falseと評価されます。$needle$haystack(0 == false)(0 === false)
バトルブトクス2014

1
Cから来る人々が使用して考えることがstrchrの機能を、しかし、PHPでそれは実際の別名だはstrstrので、strposがより良い選択です。
e2-e4 2014

38

ここに私が私の質問にたどり着いた他のいくつかの答え(+ベンチマーク)があります、それはほとんど同じです(私は尋ねたときにあなたの答えに気づいていませんでした)。


その間に私はまた、私は各関連機能のための1000000回走った私自身のベンチマークテストを、作られた(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

以下はもう1つです。この場合、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 2015

7

多くの開発者はstrposマイクロ最適化の目的で使用します。

また、使用strstrは、結果の文字列がブールコンテキストでfalseとして解釈できない場合にのみ機能します。


11
これはマイクロ最適化ではなく、ジョブに適切な関数を使用して呼び出されます。文字列の位置が必要な場合は、を呼び出しますstrpos()。その位置の後に部分文字列が必要な場合は、を呼び出しますstrstr()
Alnitak 2011

1
@Alnitak:私が言っていたこと。文字列の存在を確認したい場合は、そのための関数があります。実際にそのポジションが必要な場合は、別のポジションがあります。-実際に位置を必要とせずに位置を調べると、「仕事に適した機能を使用する」ことはほとんどありません。意図は明らかにマイクロ秒先を最適化することです。(それはあなたが引用したものではありませんか?)
マリオ2011

1
@marioですが、部分文字列が存在するかどうかを確認することだけを目的とする関数はありません。部分文字列の位置(見つかった場合)は、実際に見つけたら無料の情報です。OTOHは、strstr必要以上のことをします。それが遅い理由です。
Alnitak 2011

@Alnitak:ニュースではなく、気に留めてください。あなたはパフォーマンスの違いを指摘することに非常に固執しているようですが、それだけです。これは、マイクロ最適化の明らかな兆候です。プロファイラーでブリップは発生しません。それが違いを生むのは、コードの可読性です。
マリオ2011

@mario実際、私はパフォーマンスについてほんの少しだけ気にします。私は仕事に適切な機能を使用することに非常に気を配っています;
Alnitak 2011

0

strpos()は、干し草の山のどこに特定の針があるかを検出します。stristr()は、針が干し草の山のどこかにあるかどうかをテストします

そのため、strpos()はより高速で、メモリ消費量が少なくなります

strstr()の理由:針が文字列の先頭にある場合、strposは0を返します(したがって、=== falseでチェックする必要があります)


6
これは完全に偽の説明です。strstr()針の前後のすべてを返すため、最初に同等の処理を実行してから、strpos() その部分文字列を作成する必要があります。そこがパフォーマンスのヒットです。
Alnitak 2011

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.