首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >性能级字符串匹配

性能级字符串匹配
EN

Stack Overflow用户
提问于 2010-01-06 03:58:43
回答 2查看 3.7K关注 0票数 4

我有一个通用的DB查询函数,每次发出SQL查询时都会运行以下检查:

  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))

我知道简单的strpos()调用比执行preg_match()要快得多,但是由于我要调用preg_match()两次,所以我真的不确定哪个应该更好。

第二个选项中的S模式修饰符也给我带来了一些困惑,来自于手册:

当一个模式要被多次使用时,需要花费更多的时间来分析它,以加快匹配所需的时间。如果设置了此修饰符,则执行此额外的分析。目前,研究模式只对没有固定起始字符的非锚定模式有用。

在这种情况下,速度并不重要(否则我不会使用这个通用查询函数),但是,我仍然希望在保持简单性的同时使它运行得尽可能快。

以上选项中的哪一种我应该选择?

编辑:,我有运行一个简单的基准测试,但是我仍然不能决定哪种方法工作得更好。

下面是10,000次尝试的结果,(总时间,以秒为单位):

代码语言:javascript
复制
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尝试

代码语言:javascript
复制
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尝试

代码语言:javascript
复制
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尝试

代码语言:javascript
复制
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
        )
)

正如您所看到的,结果差别很大,这让我怀疑这是否是做基准测试的正确方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-01-08 03:16:44

我使用了以下正则表达式,因为它们看起来更快(对于匹配的和不匹配的文本):

  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)
票数 0
EN

Stack Overflow用户

发布于 2010-01-06 04:08:19

我可能不会用这些。如果没有基准测试,我无法确定,但我认为substr()stripos更快,因为它不会扫描整个字符串。假设UPDATEDELETE总是在查询开始时发生,更好的是,它们都有6个字符长,所以可以在一个substr()中完成

代码语言:javascript
复制
$queryPrefix = strtoupper(substr($query,0,6));
if ($queryPrefix == 'UPDATE' || $queryPrefix == 'DELETE') {

如果需要,可以为任何前缀空格添加一个trim(),但可能没有必要。

如果您使用UPDATE和DELETE执行嵌套查询或子查询,那么显然上面的方法无法工作,我将使用stripos()路由。如果您能够避免正则表达式而倾向于使用普通字符串函数,那么它将更快、更不复杂。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2010867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档