Php 基于性能的字符串匹配

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()快得多,但是由于我调用

我有一个通用的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
    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())都会创建一个新字符串(包括内存分配)。如果可能的话,我会避免这种情况……查询需要多长时间才能运行?这看起来像是过早的优化。