Frage

Ich habe eine generische Abfrage-Funktion DB, das jedes Mal, wenn eine SQL-Abfrage der folgenden Prüfungen ausgeführt wird ausgegeben:

  1. if (preg_match('~^(?:UPDATE|DELETE)~i', $query) === 1)
  2. if (preg_match('~^(?:UPDATE|DELETE)~iS', $query) === 1)
  3. if ((stripos($query, 'UPDATE') === 0) || (stripos($query, 'DELETE') === 0))

Ich weiß, dass ein einfacher strpos() Anruf ist viel schneller als ein preg_match() tun, aber da ich rufe strIpos() zweimal Ich bin wirklich nicht sicher, welche sollte man besser.

Das S Muster Modifikator in der zweiten Option bringt auch einige Verwirrung in meinem Kopf, aus dem Handbuch:

  

Wenn ein Muster verwendet werden soll   mehrmals, ist es wert,   es mehr Zeit, um die Analyse zu   beschleunigt die Zeit für die Übereinstimmungen aufgenommen.   Wenn dieser Modifikator gesetzt ist, dann ist diese   zusätzliche Analyse durchgeführt wird. Beim   Derzeit ein Muster zu studieren ist nützlich   nur für nicht-verankerte Muster, die tun   nicht einen einzigen festen Start haben   Charakter.

In dieser Fall Geschwindigkeit nicht kritisch ist (sonst würde ich nicht diese allgemeine Abfrage-Funktion verwenden), aber ich würde immer noch gerne es so schnell wie möglich machen läuft unter Beibehaltung seiner Einfachheit.

Welche der oben genannten Optionen soll ich wählen?


EDIT: Ich habe eine einfache Benchmark laufen und immer noch ich nicht entscheiden kann, welche Methode besser funktioniert.

Hier sind die Ergebnisse für 10.000 Versuche (Gesamtzeit, in Sekunden):

Array
(
    [match] => Array
        (
            [stripos] => 0.0965
            [preg_match] => 0.2445
            [preg_match?] => 0.1227
            [preg_match?S] => 0.0863
        )

    [no-match] => Array
        (
            [stripos] => 0.1165
            [preg_match] => 0.0812
            [preg_match?] => 0.0809
            [preg_match?S] => 0.0829
        )
)

100.000 versucht :

Array
(
    [match] => Array
        (
            [stripos] => 1.2049
            [preg_match] => 1.5079
            [preg_match?] => 1.5564
            [preg_match?S] => 1.5857
        )

    [no-match] => Array
        (
            [stripos] => 1.4833
            [preg_match] => 0.8853
            [preg_match?] => 0.8645
            [preg_match?S] => 0.8986
        )
)

1.000.000 versucht :

Array
(
    [match] => Array
        (
            [stripos] => 9.4555
            [preg_match] => 8.7634
            [preg_match?] => 9.0834
            [preg_match?S] => 9.1629
        )

    [no-match] => Array
        (
            [stripos] => 13.4344
            [preg_match] => 9.6041
            [preg_match?] => 10.5849
            [preg_match?S] => 8.8814
        )
)

10.000.000 versucht :

Array
(
    [match] => Array
        (
            [stripos] => 86.3218
            [preg_match] => 93.6755
            [preg_match?] => 92.0910
            [preg_match?S] => 105.4128
        )

    [no-match] => Array
        (
            [stripos] => 150.9792
            [preg_match] => 111.2088
            [preg_match?] => 100.7903
            [preg_match?S] => 88.1984
        )
)

Wie Sie die Ergebnisse sind sehr unterschiedlich sehen können, das macht mich frage mich, ob dies der richtige Weg ist, einen Maßstab zu tun.

War es hilfreich?

Lösung 2

Ich ging mit dem folgenden regulären Ausdrücke, da sie scheinen schneller zu sein (auf abgestimmt und nicht-angepassten Text):

  1. if (preg_match('~^(?:INSERT|REPLACE)~i', $query) === 1)
  2. else if (preg_match('~^(?:UPDATE|DELETE)~i', $query) === 1)
  3. else if (preg_match('~^(?:SELECT|EXPLAIN)~i', $query) === 1)

Andere Tipps

Ich würde wahrscheinlich nicht irgendwelche von denen verwenden. Ich kann ohne Benchmarking nicht sicher sein, aber ich denke, ein substr() eine schnellere Option als stripos wäre, da wäre es nicht die gesamte Zeichenfolge scannen. Unter der Annahme, UPDATE und DELETE tritt immer am Anfang einer Abfrage, und noch besser, sie sind beide genau 6 Zeichen lang, so dass Sie es in einem einzigen substr() tun könnten:

$queryPrefix = strtoupper(substr($query,0,6));
if ($queryPrefix == 'UPDATE' || $queryPrefix == 'DELETE') {

Wenn Sie benötigt, können es für jeden vorangestelltes Leerzeichen ein trim() hinzufügen könnte, aber es ist wahrscheinlich nicht erforderlich.

Wenn Sie verschachtelt tut oder Unterabfragen mit UPDATE und DELETE, dann natürlich das obige Verfahren nicht funktionieren würde, und ich würde mit dem stripos() Weg gehen. Wenn Sie reguläre Ausdrücke für normale String-Funktionen vermeiden können, wird es schneller und weniger kompliziert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top