Python – Medindo tempo de execução

cleitonbueno_python_time_timeitQuem nunca preciso medir o tempo de algo? Digo, em foco a programação e principalmente quando se aplica Profiling, tempo as vezes é muito importante medir. Uma coisa é fazer algo funcionar, outra coisa é com eficiência e outra é ter desempenho, muitas vezes fazemos o primeiro e esquecemos o resto, eu já quebrei a cabeça em cima de uma função tentando otimização e aplicando tudo o que eu sabia e o problema não era meu e sim de uma função de uma lib pronta. Enfim, vamos ver como podemos medir tempo de execução de programas ou trechos de códigos em python.

Em C, quem já precisou, usando a library time.h podemos criar um tipo com time_t ou clock_t e utilizando duas variáveis, chamar no inicio e no fim, no final realiza uma matemática simples, normalmente substração e temos o tempo gasto, normalmente em ms(milissegundos). E quem disse que em Python é diferente? Vamos ao código exemplo, abaixo e logo em seguida adicionar a forma de medir o tempo.

Minimizei ao máximo para um exemplo legal, para os testes, visto que foi tirado de um programa real a ideia do artigo, tenho uma lista com nomes my_list_name um pouco mais abaixo na linha12 eu uso sorted() para ordenar minha lista e armazenar em my_list_sorted o que quero medir aqui é entre as duas opções qual é a mais rápida, pode haver outras maneiras de tonar mais rápida ou eficiente, mas para o exemplo as duas vão apresentar resultados interessantes ;)

Primeiramente, vamos “medir” com o time do Linux.

Uma breve explicação do que o Linux esta nos dizendo:
real: Tempo total ocorrido do inicio ao encerramento da aplicação
user: Tempo gasto de CPU no user-space, no modo usuario dentro do processo
sys: Tempo gasto de CPU dentro do kernel, funções e chamadas especificas do kernel

Uma referencia legal pode ser visto man do time.

OBS: Não é boa pratica dizer que real é user + sys, faça um teste com uma aplicação com multithreading e veja o resultado.

Vamos agora comentar a Opção 1 e ver o tempo da Opção 2:

Vamos novamente ao terminal e ver o tempo agora.

Ok, analisando nossa segunda opção, pareceu que se saiu melhor, mas nossa aplicação é pequena, e se antes disso executasse outras funções e queremos por exemplo, ver o que é mais rápido a Opção 1 ou a Opção 2, vamos ver agora o Time, modifique o nosso código conforme abaixo.

Hum, legal! Agora vou medir antes de entrar de executar a Opção 1 e parar quando sair e o mesmo na Opção 2 e imprimir na tela o tempo, vamos ver.

Nossa! Neste caso List Comprehensions mandou muito bem heim.

Maravilha, vimos como medir o tempo de execução de um trecho de código no Python, pode estender fácil para funções e afins, mas descobri algo muito interessante neste aspecto no Python, quando passeando encontrei no Debugging and Profiling o Timeit.

A função timeit.timeit() e timeit.repeat(), segundo a documentação segue sua estrutura:

timeit.timeit(stmt=’pass’, setup=’pass’, timer=, number=1000000)
timeit.repeat(stmt=’pass’, setup=’pass’, timer=, repeat=3, number=1000000)

Os parâmetros importantes e bom saber são:

Statement ou stmt: A função que sera “testada”
setup: O código básico para iniciar e realizar os testes
number: Numero de loops a realizar com a função, valor padrão é 1000000
repeat: Quantas baterias de number serão feitas (valido somente no timeit.repeat()

Vamos agora, passar nossos dois códigos em duas funções opcao1() e opcao2() e implementar os testes com timeit.

Importamos o timeit, colocamos em duas funções o que queremos “testar” e inserimos duas variaveis tempo_op1 e tempo_op2 que recebem timeit.timeit(), a estrutura é primeiro a função, segundo setup basico para inicializar e utilizar a função e no caso, coloquei numero de 10 loops, visto que 1.000.000 com esses prints seria um pouco exaustivo não?

Vamos ver a saída.

Hum, agora vamos fazer com 10, 100 e 1000 loops:

Vamos ver a saída:

Para encerrar, agora uma amostra usando time.repeat().

Vamos fazer 10 loops com 5 baterias, vamos ver a saída:

Ele nos devolve uma lista com o tempo de cada bateria.

Gostaram? Viu que Python não é só uma linguagem fácil e excelente para prototipar, quanto mais você mergulha mais ela se torna poderosa e mostra recursos. Isso porque os testes foram focado em uma ideia fixa, não abordei cProfile, profile, trace, pstats, hotshot, line_profiler, memory_profiler, pypy, psyco da pra ver que tem bastante coisa pra falar ainda né?

Espero que tenham gostado e até a próxima!

 

Referências

http://man7.org/linux/man-pages/man1/time.1.html
https://docs.python.org/2/library/timeit.html
https://docs.python.org/2/library/time.html
https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions
https://docs.python.org/2/library/debug.html
Medindo tempo de execução de código Python

Share Button

CC BY-NC-SA 4.0 Python – Medindo tempo de execução by Cleiton Bueno is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.