性能的に文字列マッチング
-
18-09-2019 - |
質問
私は汎用DBクエリ機能が以下のチェック時にSQLクエリを発行:
if (preg_match('~^(?:UPDATE|DELETE)~i', $query) === 1)
if (preg_match('~^(?:UPDATE|DELETE)~iS', $query) === 1)
if ((stripos($query, 'UPDATE') === 0) || (stripos($query, 'DELETE') === 0))
そんな簡単な strpos()
通話方法によっ preg_match()
, しかし、今呼び出し strIpos()
回 思いつきを行います。
の S
パターンの修飾子は、次のオプションをもたらかの混乱が、私の頭からのマニュアル:
パターンがある使用されるのか 数時代を過ごすには最適のリゾー 時間を解析するために 速断時間のマッチングです。この修飾子を設定し、この 追加分析を行います。時 現在、パターンに役立つ 非固定パターンとい を持たない単一固定開始 文字です。
この場合には速する必要はありません(その他いかないこのリクエリ機能ですが、まだまだいくとして実行可能な限り速く維持でシンプルさが人気です。
る上記のオプションを選んだら良いでしょうか?
編集: 私 走簡単なベンチマーク がんを決める方法にしようとしています。
ここでの結果 10,000う 総時間を秒で指定):
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う:
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う:
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う:
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
)
)
ご覧のとおり結果は異なり、こう場合には、正しい方法にはベンチマーク
解決 2
私は、以下のregexes来るように思われる高速(一致した不一致テキスト):
if (preg_match('~^(?:INSERT|REPLACE)~i', $query) === 1)
else if (preg_match('~^(?:UPDATE|DELETE)~i', $query) === 1)
else if (preg_match('~^(?:SELECT|EXPLAIN)~i', $query) === 1)
他のヒント
私はおそらくそれらのいずれかを使用することはありません。私はベンチマーキングせずに確認することはできませんが、私はそれが文字列全体をスキャンしないと同じように、substr()
がstripos
より速いオプションになると思います。 UPDATE
とDELETE
と仮定すると、常に、クエリの開始時に発生し、より良いあなたは、単一のsubstr()
でそれを行うことができるように、彼らは、両方とも正確に6文字です。
$queryPrefix = strtoupper(substr($query,0,6));
if ($queryPrefix == 'UPDATE' || $queryPrefix == 'DELETE') {
あなたは、あなたが任意のプレフィックス空白のためにそこにtrim()
を追加することができますする必要がある場合、それはおそらく必要ありません。
、その後、明らかに上記の方法では動作しないだろう、と私はstripos()
ルートで行くと思います。あなたは、通常の文字列関数の賛成で正規表現を避けることができれば、それはより速く、より複雑になります。