Usando Python Timeit para cronometrar seu código

Neste tutorial, você aprenderá como usar a função timeit do módulo timeit do Python. Você aprenderá como cronometrar expressões e funções simples em Python.

Cronometrar seu código pode ajudá-lo a obter uma estimativa do tempo de execução de um trecho de código e também identificar as seções do código que precisam ser otimizadas.

Começaremos aprendendo a sintaxe da função timeit do Python. E então codificaremos exemplos para entender como usá-lo para cronometrar blocos de código e funções em seu módulo Python. Vamos começar.

Como usar a função timeit do Python

O módulo timeit faz parte da biblioteca padrão do Python e você pode importá-lo:

import timeit

A sintaxe para usar a função timeit do módulo timeit é a seguinte:

timeit.timeit(stmt, setup, number)

Aqui:

  • stmt é o pedaço de código cujo tempo de execução deve ser medido. Você pode especificá-lo como uma string Python simples ou uma string multilinha, ou passar o nome do callable.
  • Como o nome sugere, a configuração denota a parte do código que precisa ser executada apenas uma vez, geralmente como um pré-requisito para a execução do stmt. Por exemplo, suponha que você esteja calculando o tempo de execução para a criação de um array NumPy. Nesse caso, importar numpy é o código de configuração e a criação real é a instrução a ser cronometrada.
  • O número do parâmetro denota o número de vezes que o stmt é executado. O valor padrão do número é 1 milhão (1.000.000), mas você também pode definir esse parâmetro para qualquer outro valor de sua escolha.

Agora que aprendemos a sintaxe para usar a função timeit(), vamos começar a codificar alguns exemplos.

Cronometrando Expressões Python Simples

Nesta seção, tentaremos medir o tempo de execução de expressões Python simples usando timeit.

Inicie um Python REPL e execute os exemplos de código a seguir. Aqui, estamos calculando o tempo de execução das operações de exponenciação e divisão de piso para 10.000 e 100.000 execuções.

  Como clicar com o botão direito em qualquer Mac usando um trackpad, mouse ou teclado

Observe que passamos a instrução a ser cronometrada como uma string Python e usamos 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 Python timeit na linha de comando

Você também pode usar timeit na linha de comando. Aqui está o equivalente de linha de comando da chamada de função timeit:

$ python-m timeit -n [number] -s [setup] [stmt]
  • python -m timeit representa que executamos timeit como o módulo principal.
  • n é uma opção de linha de comando que denota o número de vezes que o código deve ser executado. Isso é equivalente ao argumento de número na chamada da função timeit().
  • Você pode usar a opção -s para definir o código de configuração.

Aqui, reescrevemos o exemplo anterior usando o equivalente da linha de comando:

$ python -m timeit -n 100000 '3**4;3//4'
100000 loops, best of 5: 35.8 nsec per loop

Neste exemplo, calculamos o tempo de execução da função interna len(). A inicialização da string é o código de configuração passado usando a 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 obtemos o tempo de execução para melhor de 5 execuções. O que isto significa? Ao executar timeit na linha de comando, a opção de repetição r é definida com o valor padrão de 5. Isso significa que a execução do stmt pelo número especificado de vezes é repetida cinco vezes e o melhor dos tempos de execução é retornado.

Análise de métodos de reversão de strings usando timeit

Ao trabalhar com strings Python, você pode querer invertê-las. As duas abordagens mais comuns para reversão de string são as seguintes:

  • Usando fatiamento de string
  • Usando a função reversed() e o método join()

Strings reversas do Python usando fatias de strings

Vamos ver como o fatiamento de string funciona e como você pode usá-lo para inverter uma string Python. Usando a sintaxe some-string[start:stop] retorna uma fatia da string começando no início do índice e se estendendo até a parada do índice-1. Vamos dar um exemplo.

Considere a seguinte string ‘Python’. A string tem comprimento 6 e a lista de índices é 0, 1, 2 até 5.

  Como emparelhar dois conjuntos de AirPods com o mesmo iPhone

>>> string_1 = 'Python'

Ao especificar os valores inicial e final, você obtém uma fatia de string que se estende do início ao fim-1. Portanto, string_1[1:4] retorna ‘yth’.

>>> string_1 = 'Python'
>>> string_1[1:4]
'yth'

Quando você não especifica o valor inicial, o valor inicial padrão de zero é usado e a fatia começa no índice zero e se estende até parar – 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ê não inclui o índice de parada, vê que a fatia começa no índice inicial (1) e se estende até o final da string.

>>> string_1[1:]
'ython'

Ignorar 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 começando em 1 estendendo-se até 4 (excluindo o ponto final 5) contendo cada segundo caractere.

>>> string_1[1:5:2]
'yh'

Quando você usa uma etapa negativa, pode obter uma fatia começando no final da string. Com o passo definido como -2, string_1[5:2:-2] dá a seguinte fatia:

>>> string_1[5:2:-2]
'nh'

Portanto, para obter uma cópia invertida da string, pulamos os valores de início e parada e definimos o passo como -1, conforme mostrado:

>>> string_1[::-1]
'nohtyP'

Resumindo: cadeia[::-1] retorna uma cópia invertida da string.

Invertendo Strings Usando Funções Integradas e Métodos de String

A função reversed() integrada em Python retornará um iterador reverso sobre os elementos da string.

>>> string_1 = 'Python'
>>> reversed(string_1)
<reversed object at 0x00BEAF70>

Assim, você pode percorrer o iterador reverso usando um loop for:

for char in reversed(string_1):
    print(char)

E acesse 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 sintaxe: .join(reversed(some-string)).

O trecho de código abaixo mostra alguns exemplos em que 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 queremos nenhum separador; então defina o separador como uma string vazia para obter uma cópia invertida da string:

>>> ''.join(reversed(string1))
'nohtyP'

O uso de .join(reversed(some-string)) retorna uma cópia invertida da string.

Comparando Tempos de Execução Usando timeit

Até agora, aprendemos duas abordagens para inverter strings Python. Mas qual deles é mais rápido? Vamos descobrir.

  O que é computação de borda e por que isso importa?

Em um exemplo anterior em que cronometramos expressões Python simples, não tínhamos nenhum código de configuração. Aqui, estamos invertendo a string do Python. Enquanto a operação de reversão de string é executada pelo número de vezes especificado por number, o código de configuração é a inicialização da string que será executada apenas 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 usar o método join() e a função reversed().

Funções do Python de temporização Usando timeit

Nesta seção, vamos aprender como cronometrar funções do Python com a função timeit. Dada uma lista de strings, a seguinte função hasDigit retorna a lista de strings que possuem pelo 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 medir o tempo de execução desta função Python hasDigit() usando timeit.

Vamos primeiro identificar a instrução a ser cronometrada (stmt). É a chamada para a função hasDigit() com uma lista de strings como argumento. Em seguida, vamos definir o código de configuração. Você consegue adivinhar qual deve ser o código de configuração?

Para que a chamada de função seja executada com sucesso, o código de configuração deve incluir o seguinte:

  • A definição da função hasDigit()
  • A inicialização da lista de argumentos de strings

Vamos definir o código de configuração na string de configuração, conforme mostrado 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 usar 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 usar a função timeit do Python para cronometrar expressões, funções e outros callables. Isso pode ajudá-lo a avaliar seu código, comparar os tempos de execução de diferentes implementações da mesma função e muito mais.

Vamos revisar o que aprendemos neste tutorial. Você pode usar a função timeit() com a sintaxe timeit.timeit(stmt=…,setup=…,number=…). Como alternativa, você pode executar timeit na linha de comando para cronometrar trechos de código curto.

Como próxima etapa, você pode explorar como usar outros pacotes de criação de perfil do Python, como line-profiler e memprofiler, para criar o perfil de seu código para tempo e memória, respectivamente.

Em seguida, aprenda como calcular a diferença de tempo em Python.