[Rio-pm] Performance de regex

Daniel de Oliveira Mantovani daniel.oliveira.mantovani em gmail.com
Terça Março 30 09:10:11 PDT 2010


http://swtch.com/~rsc/regexp/regexp1.html

A discussão:
http://perlmonks.org/?node_id=597262

[]'s

2010/3/23 Marcos Machado <listas em istf.com.br>:
> 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
> _______________________________________________
> Rio-pm mailing list
> Rio-pm em pm.org
> http://mail.pm.org/mailman/listinfo/rio-pm
>



-- 
"If you’ve never written anything thoughtful, then you’ve never had
any difficult, important, or interesting thoughts. That’s the secret:
people who don’t write, are people who don’t think."


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