Neste guia, você descobrirá como empregar a função timeit
do módulo homônimo em Python. Aprenderá a medir a duração de execução de expressões e funções simples no Python.
A cronometragem do seu código pode ser útil para obter uma estimativa do tempo necessário para a execução de um segmento de código, além de identificar as partes do código que podem necessitar de otimização.
Começaremos explorando a sintaxe da função timeit
do Python. Em seguida, desenvolveremos exemplos para entender como utilizá-la para medir o tempo de execução de trechos de código e funções em seu módulo Python. Vamos iniciar.
Como Utilizar a Função timeit
do Python
O módulo timeit
faz parte da biblioteca padrão do Python, e você pode importá-lo da seguinte forma:
import timeit
A estrutura para empregar a função timeit
do módulo é:
timeit.timeit(stmt, setup, number)
Onde:
stmt
é o trecho de código cujo tempo de execução deve ser avaliado. Pode ser definido como uma string Python simples, uma string multilinhas, ou você pode passar o nome de um objeto chamável (callable).setup
, como o nome sugere, representa a porção de código que necessita ser executada uma única vez, geralmente como uma condição prévia para a execução dostmt
. Por exemplo, imagine que você esteja medindo o tempo de execução para a criação de um array NumPy. Nesse caso, a importação do NumPy seria o código de configuração, e a criação do array seria a instrução a ser cronometrada.number
é o número de vezes que ostmt
será executado. O valor padrão é 1 milhão (1.000.000), mas você tem a opção de ajustar este parâmetro para qualquer outro valor desejado.
Agora que compreendemos a sintaxe para usar a função timeit()
, vamos começar a elaborar alguns exemplos práticos.
Medindo o Tempo de Expressões Python Simples
Nesta seção, tentaremos quantificar o tempo de execução de expressões Python básicas utilizando o timeit
.
Inicie um Python REPL e execute os exemplos de código a seguir. Aqui, estamos medindo o tempo de execução das operações de exponenciação e divisão inteira para 10.000 e 100.000 repetições.
Note que a instrução a ser cronometrada é passada como uma string Python, e empregamos um ponto e vírgula para separar as diferentes expressões na instrução.
>>> import timeit >>> timeit.timeit('3**4;3//4',number=10000) 0.0004020999999738706 >>> timeit.timeit('3**4;3//4',number=100000) 0.0013780000000451764
Executando timeit
do Python na Linha de Comando
O timeit
também pode ser utilizado diretamente da linha de comando. Aqui está o equivalente em linha de comando da chamada da função timeit
:
$ python-m timeit -n [number] -s [setup] [stmt]
python -m timeit
indica que estamos executando otimeit
como o módulo principal.n
é uma opção de linha de comando que especifica o número de vezes que o código será executado, equivalente ao argumentonumber
na chamada da funçãotimeit()
.- A opção
-s
permite definir o código de configuração.
A seguir, reescrevemos o exemplo anterior utilizando o equivalente em linha de comando:
$ python -m timeit -n 100000 '3**4;3//4' 100000 loops, best of 5: 35.8 nsec per loop
Neste exemplo, medimos o tempo de execução da função interna len()
. A inicialização da string é o código de configuração, passado através da opção s
.
$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)' 100000 loops, best of 5: 239 nsec per loop
Na saída, observe que o tempo de execução apresentado é o melhor de 5 execuções. O que isto quer dizer? Ao executar o timeit
na linha de comando, a opção de repetição r
assume o valor padrão de 5. Isto implica que a execução do stmt
pelo número especificado de vezes é repetida cinco vezes, e o melhor tempo de execução é o que é exibido.
Análise de Métodos de Inversão de Strings Usando timeit
Ao lidar com strings em Python, a necessidade de invertê-las pode surgir. As duas abordagens mais comuns para a inversão de strings são:
- Utilização de fatiamento de strings.
- Utilização da função
reversed()
e do métodojoin()
.
Invertendo Strings Python com Fatiamento de Strings
Vamos explorar como o fatiamento de strings funciona e como você pode utilizá-lo para inverter uma string Python. Ao empregar a sintaxe alguma-string[início:fim]
, uma fatia da string é retornada, começando no índice inicial e se estendendo até o índice final-1. Considere o exemplo a seguir:
Considere a string ‘Python’. A string tem um comprimento de 6, e a lista de índices é de 0, 1, 2 até 5.
>>> string_1 = 'Python'
Ao especificar os valores inicial e final, você obtém uma fatia da string que se estende do início até o fim-1. Portanto, string_1[1:4]
retorna ‘yth’.
>>> string_1 = 'Python' >>> string_1[1:4] 'yth'
Quando o valor inicial não é especificado, o valor inicial padrão de zero é empregado, e a fatia começa no índice zero, estendendo-se até o índice de parada – 1.
Aqui, o valor de parada é 3, então a fatia começa no índice 0 e vai até o índice 2.
>>> string_1[:3] 'Pyt'
Quando você omite o índice de parada, a fatia começa no índice inicial (1) e se estende até o final da string.
>>> string_1[1:] 'ython'
Omitir os valores inicial e final retorna uma fatia da string inteira.
>>> string_1[::] 'Python'
Vamos criar uma fatia com o valor do passo. Defina os valores de início, parada e etapa para 1, 5 e 2, respectivamente. Obtemos uma fatia da string que começa em 1 e se estende até 4 (excluindo o ponto final 5) contendo cada segundo caractere.
>>> string_1[1:5:2] 'yh'
Ao usar uma etapa negativa, você pode obter uma fatia começando no final da string. Com a etapa definida como -2, string_1[5:2:-2]
produz a seguinte fatia:
>>> string_1[5:2:-2] 'nh'
Portanto, para obter uma cópia invertida da string, ignoramos os valores de início e parada e definimos a etapa como -1, conforme exibido:
>>> string_1[::-1] 'nohtyP'
Resumindo: cadeia[::-1]
retorna uma cópia invertida da string.
Invertendo Strings Utilizando Funções Integradas e Métodos de String
A função integrada reversed()
em Python retorna um iterador reverso sobre os elementos da string.
>>> string_1 = 'Python' >>> reversed(string_1) <reversed object at 0x00BEAF70>
Assim, você pode iterar sobre o iterador reverso utilizando um loop for
:
for char in reversed(string_1): print(char)
E acessar os elementos da string na ordem inversa.
# Output n o h t y P
Em seguida, você pode chamar o método join()
no iterador reverso com a seguinte sintaxe:
.
O trecho de código abaixo demonstra alguns exemplos onde o separador é um hífen e um espaço em branco, respectivamente.
>>> '-'.join(reversed(string1)) 'n-o-h-t-y-P' >>> ' '.join(reversed(string1)) 'n o h t y P'
Aqui, não desejamos nenhum separador; portanto, definimos o separador como uma string vazia para obter uma cópia invertida da string:
>>> ''.join(reversed(string1)) 'nohtyP'
O uso de .join(reversed(alguma-string))
retorna uma cópia invertida da string.
Comparando Tempos de Execução Usando timeit
Até agora, aprendemos duas abordagens para inverter strings em Python. Mas qual delas é a mais rápida? Vamos descobrir.
Em um exemplo anterior, onde cronometramos expressões simples em Python, não tínhamos nenhum código de configuração. Aqui, estamos invertendo a string Python. Enquanto a operação de reversão da string é executada o número de vezes especificado por number
, o código de configuração é a inicialização da string que será executada somente uma vez.
>>> import timeit >>> timeit.timeit(stmt="string_1[::-1]", setup = "string_1 = 'Python'", number = 100000) 0.04951830000001678 >>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000) 0.12858760000000302
Para o mesmo número de execuções para inverter a string fornecida, a abordagem de fatiamento de string é mais rápida do que o método join()
combinado com a função reversed()
.
Medindo Funções Python Usando timeit
Nesta seção, vamos explorar como medir o tempo de execução de funções Python com a função timeit
. Dada uma lista de strings, a seguinte função hasDigit
retorna a lista de strings que contêm ao menos um dígito.
def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit
Agora, gostaríamos de avaliar o tempo de execução desta função Python hasDigit()
utilizando timeit
.
Inicialmente, vamos identificar a instrução a ser cronometrada (stmt
). É a chamada à função hasDigit()
com uma lista de strings como argumento. Em seguida, definiremos o código de configuração. Você consegue adivinhar qual deve ser o código de configuração?
Para que a chamada da função seja executada com sucesso, o código de configuração precisa incluir:
- A definição da função
hasDigit()
. - A inicialização da lista de strings que serão passadas como argumento.
Vamos definir o código de configuração na string de configuração, como exibido abaixo:
setup = """ def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit thislist=['puffin3','7frost','blue'] """
Em seguida, podemos utilizar a função timeit
e obter o tempo de execução da função hasDigit()
para 100.000 execuções.
import timeit timeit.timeit('hasDigit(thislist)',setup=setup,number=100000)
# Output 0.2810094920000097
Conclusão
Você aprendeu a empregar a função timeit
do Python para medir o tempo de execução de expressões, funções e outros objetos chamáveis. Isto pode auxiliá-lo a avaliar seu código, comparar os tempos de execução de diferentes implementações da mesma funcionalidade e muito mais.
Vamos revisar o que aprendemos neste tutorial. Você pode empregar a função timeit()
com a sintaxe timeit.timeit(stmt=…,setup=…,number=…)
. Alternativamente, você pode executar o timeit
na linha de comando para cronometrar pequenos trechos de código.
Como próximo passo, você pode explorar como empregar outros pacotes de perfilagem do Python, como o line-profiler
e o memprofiler
, para gerar perfis do seu código em relação ao tempo e ao uso de memória, respectivamente.
Em seguida, aprenda a calcular a diferença de tempo em Python.