Pergunta

Eu tenho uma função de consulta DB genérico que executa as seguintes verificações cada vez uma consulta SQL é emitido:

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

Eu sei que uma chamada strpos() simples é muito mais rápido do que fazer uma preg_match(), no entanto desde que eu estou chamando strIpos() duas vezes Eu realmente não estou certo de que se deve ter um melhor desempenho.

O modificador padrão S na segunda opção também traz alguma confusão na minha cabeça, a partir do manual:

Quando um padrão que vai ser usado várias vezes, vale a pena gastar mais tempo analisando-o, a fim de acelerar o tempo necessário para correspondência. Se este modificador é definido, então este análise adicional é executada. em Presentemente, o estudo de um padrão é útil apenas para os padrões não-ancorada que fazer não ter um único fixo de partida caráter.

Neste velocidade caso não é crítica (caso contrário eu não estaria usando esta função consulta genérico), mas eu ainda gostaria de torná-lo correr tão rápido quanto possível, mantendo a sua simplicidade.

Qual das opções acima devo escolher?


EDIT: Não tenho executar um referência simples e ainda assim eu não pode decidir qual método funciona melhor.

Aqui estão os resultados para 10.000 tentativas (tempo total, em segundos):

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 tentativas :

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 tentativas :

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 tentativas :

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

Como você pode ver os resultados variam muito, isso me faz pensar se esta é a maneira correta de fazer um ponto de referência.

Foi útil?

Solução 2

Eu fui com as seguintes expressões regulares desde que parecem ser mais rápido (no combinado e não combinado texto):

  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)

Outras dicas

Eu provavelmente não usar qualquer um desses. Eu não posso ter certeza sem aferição, mas acho que um substr() seria uma opção mais rápido do que stripos, uma vez que não verificar toda a string. Assumindo UPDATE e DELETE sempre ocorrem no início de uma consulta, e ainda melhor, ambos são exatamente 6 caracteres, de modo que você poderia fazê-lo em um único substr():

$queryPrefix = strtoupper(substr($query,0,6));
if ($queryPrefix == 'UPDATE' || $queryPrefix == 'DELETE') {

Se você precisava, você pode adicionar um trim() lá para qualquer espaço em branco prefixado, mas provavelmente não é necessário.

Se você está fazendo aninhados ou sub-consultas com UPDATE e DELETE, então, obviamente, o método acima não iria funcionar, e eu iria com a rota stripos(). Se você pode evitar expressões regulares em favor das funções normais de cordas, será mais rápido e menos complicado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top