[Rio-pm] Performance de regex

Marcos Machado listas em istf.com.br
Terça Março 23 13:57:31 PDT 2010


Em 22 de março de 2010 20:26, breno <breno em rio.pm.org> escreveu:

> grande MM, pode fazer um teste pra mim?
>

Mas é claro! :)



> se as strings procuradas não são expressões regulares, experimente:
>

Não são mesmo. São:

string1 = prompt
string2 = commit

Já vou deixá-las no código.



> cat OLD.log | perl -nle 'print if index($_,q[string]) != 0 and
> index($_,q[string2]) != -1' > NEW.log


index(string, substring) retorna o índice da substring dentro de $_
> (começando por 0) e retorna -1 se a string nao for encontrada. No
> código acima, estamos imprimindo apenas se "string" não estiver no
> início e "string2" não estiver na frase.
>

Para a última condição, index($_,q[string2]) precisa ser == a -1, e não !=,
correto?

O resultado foi:

$ time cat OLD.log | perl -nle 'print if index($_,q[prompt]) != 0 and
index($_,q[commit]) == -1' > NEW.log

real 0m38.238s
user 0m5.884s
sys 0m6.248s


Para mantermos a comparação com minha pergunta original:

$ time cat OLD.log | perl -nle 'print if !/^prompt/ && !/commit/;' > NEW.log

real 0m40.017s
user 0m5.532s
sys 0m6.300s

Meu primeiro teste leeeento:

$ time cat OLD.log | perl -nle 'print if !/^prompt|commit/;' > NEW.log

real 5m5.918s
user 4m51.326s
sys 0m7.392s


Se quiser brincar, podemos também voltar à expressões regulares e
> tentar estudar o escalar antes de aplicar a ER:
>
> cat OLD.log | perl -nle 'study; print if !/^string1|string2/' > NEW.log
>

$ time cat OLD.log| perl -nle 'study; print if !/^prompt|commit/' > NEW.log

real 4m48.147s
user 4m34.873s
sys 0m7.820s



>
> cat OLD.log | perl -nle 'study; print if !/^string1/ && !/string2/' >
> NEW.log
>

$ time cat OLD.log| perl -nle 'study; print if !/^prompt/ && !/commit/' >
NEW.log

real 0m41.106s
user 0m9.957s
sys 0m6.924s


como é um teste relativamente simples, não sei o ganho exato disso
> (pode ser até que piore o desempenho). Outra alternativa é o //o, que
> não achei na documentação mas se não me falha a memória serve pra
> pré-compilar e otimizar ERs estáticas (como a sua):
>
> cat OLD.log | perl -nle 'print if !/^string1|string2/o' > NEW.log
>

$ time cat OLD.log| perl -nle 'print if !/^prompt|commit/o' > NEW.log

real 5m11.024s
user 4m57.051s
sys 0m7.624s



>
> cat OLD.log | perl -nle 'print if !/^string1/o && !/string2/o' > NEW.log
>

$ time cat OLD.log| perl -nle 'print if !/^prompt/o && !/commit/o' > NEW.log

real 0m42.083s
user 0m5.232s
sys 0m6.912s


de repente até juntar isso com o study, sei lá. Ainda aposto no
> 'index' pra ser o mais rápido ;-)
>

Bom, eu não usei um ambiente de teste completamente livre de interferências,
mas acho que deu para ter uma idéia que a grande diferença é mesmo o OU
dentro da regex. De resto ficou tudo muito próximo, com o index ligeiramente
mais ligeiro. :)

[]s, MM
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/rio-pm/attachments/20100323/bb7a9a4b/attachment.html>


Mais detalhes sobre a lista de discussão Rio-pm