[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