2 Stimmen

preg_replace Geschwindigkeitsoptimierung

Wenn man sich die akzeptierte Antwort von Entfernen aller Zeichen aus einer Zeichenkette, wobei Zahlen übrig bleiben fügte der Autor eine + nach dem Ausdruck

$str = preg_replace('/[^0-9.]+/', '', $str);

um zu entfernende Teilstrings anstelle einzelner Vorkommen zu finden. Für die Funktionalität der + ist fakultativ. Aber ich habe mich gefragt, ob das Hinzufügen der + schneller ist oder nicht. (Oder gibt es gar keinen Unterschied?)

Ich gehe davon aus, dass es schneller ist, weil weniger Zeichenfolgen und weniger Speicher benötigt werden. Aber ich könnte auch verstehen, dass komplexere Regex-Ausdrücke langsamer sind als einfache.

Sollte man also bei der Verwendung dieser Technik zum Entfernen von Teilstrings versuchen, große oder kleine Teilstrings zu finden?

1voto

goat Punkte 30238

Interpretieren Sie nicht zu viel in die Benchmark-Ergebnisse hinein. Es ist unglaublich schwer, sie gut zu machen. Das Einzige, was Sie daraus ableiten sollten, ist, dass die Wiederholung bei bestimmten Arten von Zeichenketten, bei denen die Spanne der Wiederholung lang ist, schneller sein kann.

Diese Art von Dingen, die sich leicht mit einer anderen Version von PCRE ändern können.

function tst($pat, $str) {
    $start = microtime(true);
    preg\_replace($pat, '', $str);
    return microtime(true) - $start;
}
$strs = array(
    'letters' => str\_repeat("a", 20000),
    'numbers' => str\_repeat("1", 20000),
    'mostly\_letters' => str\_repeat("aaaaaaaaaaaaa5", 20000),
    'mostly\_numbers' => str\_repeat("5555555555555a", 20000)
);
$pats = array(
    'rep' => '/\[^0-9.\]+/',
    'norep' => '/\[^0-9.\]/'
);

//precompile patterns(php caches them per script) and warm up microtime
microtime(true);
preg\_replace($pats\['rep'\], '', 'foo');
preg\_replace($pats\['norep'\], '', 'foo');

foreach ($strs as $strname => $str) {
    echo "$strname\\n";
    foreach ($pats as $patname => $pat) {
        printf("%10s    %.5f\\n", $patname, tst($pat, $str));
    }
}

1voto

Veger Punkte 35866

Ich habe einige Geschwindigkeitstests durchgeführt als chris vorgeschlagen. Verglichen mit seinem Code I:

  • ein str_replace zum Vergleich hinzugefügt:

    $str_replace_array = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.');

    function tst($pat, $str) { global $str_replace_array; $start = microtime(true); if($pat == '') str_replace($str_replace_array, '', $str); else preg_replace($pat, '', $str); return microtime(true) - $start; }

  • alle Zeichenketten die gleiche Länge haben, damit die Ergebnisse besser verglichen werden können

Die Ergebnisse in:

letters
         rep    0.00298
       norep    0.06953
 str_replace    0.00406

numbers
         rep    0.02867
       norep    0.02612
 str_replace    0.01242

mostly_letters
         rep    0.00931
       norep    0.06649
 str_replace    0.00593

mostly_numbers
         rep    0.03285
       norep    0.02942
 str_replace    0.01359

Es zeigt, dass die sich wiederholende Regex (mit dem + hinzugefügt) ist viel schneller, wenn größere Blöcke ersetzt werden (weniger Speicherverwaltung?) Aber keine Wiederholung Regex ist etwas schneller, wenn nicht viel ersetzt werden muss.

Außerdem kann str_replace ist grundsätzlich immer schneller (doppelt so schnell) als die Regex-Ersetzung, es sei denn, eine Regex stimmt mit der gesamten Zeichenkette überein.

0voto

mck89 Punkte 18347

Ich habe keine Tests durchgeführt, aber mit dem + stimmen mehr Zeichen überein, so dass der Ersetzungsvorgang weniger oft ausgeführt werden sollte. Wenn Sie das + nicht in die Regexp schreiben, wird die Ersetzung für jedes Zeichen durchgeführt, anstatt eine ganze Teilzeichenkette zu ersetzen, daher denke ich, dass es langsamer ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X