2016-07-01 19 views
0

Es wurden Fragen gestellt, die schneller sind strpos oder preg_match, aber ich bin interessiert zu wissen, welche die geringsten Speicher- und CPU-Ressourcen verwendet.strpos vs. preg_match - Speicher- und Ressourcenunterschiede

ich eine Linie für einen von 5 Treffern überprüfen wollen:

if (strpos($key, 'matchA') !== false || strpos($key, 'matchB') !== false || strpos($key, 'matchC') !== false || strpos($key, 'matchD') !== false || strpos($key, 'matchE') !== false) 

if (preg_match("~(matchA|matchB|matchC|matchD|matchE)~i",$key, $match)) 

Was ist der beste Weg ist, auf dem Server dies mit der geringsten Belastung zu tun?

+2

Diese Frage eignet sich besser für Code Review Forum. http://codereview.stackexchange.com – Jeet

+0

OK Danke - ich poste es dort auf. Danke – Tom

+0

Ich denke, dass diese Frage auch auf SO gültig ist. – Eiko

Antwort

1

Jeffrey Friedl Reguläre Ausdrücke sagte, dass die in nicht-Regex Funktionen wie strpos() gebaut Verwendung und str_match() ist immer besser und schneller als preg_match() mit (vorausgesetzt, Sie die Preg-Suite verwenden) vorausgesetzt, dass Ihr Match Text ist kein Muster.

0

Ich war neugierig, so schrieb ich folgendes kurzes Skript:

<?php 

$keys = [ 
    "veryshort", 
    "veryvertlongstringhereveryvertlongstringhereveryvertlongstringhereveryvertlongstringhereveryvertlongstringhereveryvertlongstringhere", 
    "shortstringwithmatchBintheresomewhere", 
    uniqid("",true).uniqid("",true).uniqid("",true).uniqid("",true).uniqid("",true).uniqid("",true).uniqid("",true).uniqid("",true).uniqid("",true) //just random stuff 
]; 
$ops = 1000000; 

foreach ($keys as $key) { 
    $mt = microtime(true); 


    for ($i = 0;$i < $ops;$i++) { 
     $bool = strpos($key, 'matchA') !== false || strpos($key, 'matchB') !== false || strpos($key, 'matchC') !== false || strpos($key, 'matchD') !== false || strpos($key, 'matchE') !== false; 
    } 

    $mtEnd = microtime(true); 
    echo PHP_EOL."String $key".PHP_EOL; 
    echo "StrPos".PHP_EOL; 
    echo "Total time: ".($mtEnd-$mt).PHP_EOL; 
    echo "Average time: ".($mtEnd-$mt)/$ops.PHP_EOL; 

    $mt = microtime(true); 
    for ($i = 0;$i < $ops;$i++) { 
     $bool = preg_match("~(matchA|matchB|matchC|matchD|matchE)~i",$key, $match); 
    } 
    $mtEnd = microtime(true); 
    echo "preg_match".PHP_EOL; 
    echo "Total time: ".($mtEnd-$mt).PHP_EOL; 
    echo "Average time: ".($mtEnd-$mt)/$ops.PHP_EOL; 

} 

Dies ist das Ergebnis, das ich bekam.

String veryshort 
StrPos 
Total time: 0.4722261428833 
Average time: 4.722261428833E-7 
preg_match 
Total time: 0.39836096763611 
Average time: 3.9836096763611E-7 

String veryvertlongstringhereveryvertlongstringhereveryvertlongstringhereveryvertlongstringhereveryvertlongstringhereveryvertlongstringhere 
StrPos 
Total time: 0.49143600463867 
Average time: 4.9143600463867E-7 
preg_match 
Total time: 0.4594030380249 
Average time: 4.594030380249E-7 

String shortstringwithmatchBintheresomewhere 
StrPos 
Total time: 0.21032190322876 
Average time: 2.1032190322876E-7 
preg_match 
Total time: 0.6224000453949 
Average time: 6.224000453949E-7 

String 577625b20d9632.50190056577625b20d9798.81879058577625b20d97e6.80533504577625b20d97f9.27988846577625b20d9806.94313293577625b20d9803.05317354577625b20d9818.68372474577625b20d9818.19126932577625b20d9825.80344644 
StrPos 
Total time: 0.50694704055786 
Average time: 5.0694704055786E-7 
preg_match 
Total time: 0.4893159866333 
Average time: 4.893159866333E-7 

Meine Interpretation ist, dass ein einzelnes preg_match läuft schneller als mehrere Lauf strpos wegen Funktionsaufruf Gemeinkosten und zusätzliche Vergleiche pro Funktion, dies jedoch nicht der Fall zu sein scheint, wenn es eine Übereinstimmung innerhalb Ihr String, vielleicht weil, wenn das passiert, der zugrundeliegende Regex-Zustandsautomat seinen Zustand ändert und (vermutlich) mehr Dinge tut.

Ich denke, die Antwort ist nicht so einfach wie "A ist schneller als B", sondern "greifen Sie diesen Code, setzen Sie Ihre üblichen Anwendungsfälle in und sehen, was für Ihren speziellen Fall besser ist".

+0

Danke für Ihre Antwort, das zeigt die benötigte Zeit, nicht die verwendeten Ressourcen. Gibt es eine Möglichkeit, das zu sehen? – Tom

+1

@Tom Mir ist nichts bekannt, das Ihnen die Ressourcen einer bestimmten Funktion mitteilen kann (es gibt http://php.net/manual/en/function.memory-get-peak-usage.php), aber das ist es wahrscheinlich nicht passend mit dem obigen Code). Alles, was ich sagen kann, ist, dass sowohl preg_match als auch strpos Argumente nach Wert akzeptieren, was bedeutet, dass eine Kopie jedes übergebenen Arguments erstellt wird. Ansonsten benötigt strpos keinen zusätzlichen Speicherplatz, bin aber nicht sicher, ob es preg_match gibt, also ist es wahrscheinlich schlechter, wenn Sie 5 strpos anstelle von 1 preg_match als Ressource verwenden. – apokryfos