Php 基于性能的字符串匹配
我有一个通用的DB查询函数,它在每次发出SQL查询时运行以下检查:Php 基于性能的字符串匹配,php,regex,string,string-matching,strpos,Php,Regex,String,String Matching,Strpos,我有一个通用的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()快得多,但是由于我调用
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
pattern修饰符也给我的头脑带来了一些混乱,手册中提到:
当要使用某个模式时
好几次,这是值得花费的
更多的时间来分析它,以便
加快匹配所需的时间。
如果设置了此修改器,则
进行额外的分析。在
目前,研究模式是有用的
仅适用于这样做的非锚定图案
没有一个固定的启动
性格
在这种情况下,速度并不重要(否则我不会使用这个通用查询函数),但是,我仍然希望在保持简单性的同时使它尽可能快地运行
我应该选择上述选项中的哪一个?
编辑:我已经尝试过,但仍然无法决定哪种方法效果更好 以下是10000次尝试的结果(所用总时间,以秒为单位): 100000次尝试:
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
)
)
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
)
)
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
)
)
1000000次尝试:
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
)
)
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
)
)
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
)
)
10000000次尝试:
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
)
)
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
)
)
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
)
)
正如您可以看到的,结果差异很大,这让我怀疑这是否是进行基准测试的正确方法。我可能不会使用这些方法中的任何一种。如果没有基准测试,我无法确定,但我认为
substr()
比stripos
更快,因为它不会扫描整个字符串。假设UPDATE
和DELETE
总是在查询开始时出现,甚至更好的是,它们都正好有6个字符长,因此您可以在单个substr()中完成:
如果需要,您可以为任何前缀空白添加一个trim()
,但这可能不是必需的
如果您使用UPDATE和DELETE执行嵌套查询或子查询,那么显然上述方法不起作用,我将使用stripos()
路由。如果您可以避免使用正则表达式而使用普通字符串函数,那么它将更快、更简单。我使用了以下正则表达式,因为它们似乎更快(在匹配和非匹配文本上):
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()
+strotupper()
是否比stripos()
快),但有一个问题:我无法检查REPLACE
或EXPLAIN
类型的查询,因为它们都有7个字符。所有这些函数(substr()、trim()、strotupper())都会创建一个新字符串(包括内存分配)。如果可能的话,我会避免这种情况……查询需要多长时间才能运行?这看起来像是过早的优化。