我有一个通用的数据库查询功能,每次发出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模式修饰符也会在手册中引起一些混乱:
When a pattern is going to be used
several times, it is worth spending
more time analyzing it in order to
speed up the time taken for matching.
If this modifier is set, then this
extra analysis is performed. At
present, studying a pattern is useful
only for non-anchored patterns that do
not have a single fixed starting
character.
在这种情况下,速度并不重要(否则我不会使用这种通用查询功能)但是,我仍然希望尽可能快地运行它,同时保持它的简单性.
我应该选择以上哪个选项?
编辑:我已经run a simple benchmark仍然无法确定哪种方法更好.
以下是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
)
)
正如您所看到的结果差异很大,这让我想知道这是否是正确的基准测试方法.
最佳答案 我可能不会使用任何这些.我不能确定没有基准测试,但我认为substr()将是一个比stripos更快的选项,因为它不会扫描整个字符串.假设UPDATE和DELETE总是出现在查询的开头,甚至更好,它们都是6个字符长,所以你可以在一个substr()中完成它:
$queryPrefix = strtoupper(substr($query,0,6));
if ($queryPrefix == 'UPDATE' || $queryPrefix == 'DELETE') {
如果需要,可以在那里为任何前缀空格添加trim(),但可能没有必要.
如果您正在使用UPDATE和DELETE进行嵌套或子查询,那么显然上面的方法将不起作用,并且我将使用stripos()路由.如果你可以避免正则表达式支持普通的字符串函数,它会更快,更简单.