Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda Medindo o Desempenho de Funções | Compreensão e Medição de Desempenho
Técnicas de Otimização em Python

bookMedindo o Desempenho de Funções

Embora medir trechos de código baseados em strings possa ser suficiente em alguns casos, essa abordagem carece de flexibilidade. Utilizar o timeit com funções oferece uma maneira mais eficaz de medir o desempenho, e decoradores simplificam o processo de mensuração do desempenho de várias funções de forma limpa e modular.

Utilizando timeit com Funções

O timeit pode medir o desempenho de funções diretamente ao receber um callable (ou seja, uma função) em vez de uma string. Isso é mais flexível e legível do que usar strings, especialmente quando se deseja avaliar funções complexas.

1234567891011121314
import timeit import numpy as np # Function to test def generate_squares(): return np.array([x ** 2 for x in range(1000000)]) # Measure time using a callable (function) iterations = 15 execution_time = timeit.timeit(generate_squares, number=iterations) # Calculate average time per run average_time = execution_time / iterations print(f'Average execution time: {average_time:.6f} seconds')
copy

Passa-se generate_squares como a função (callable) a ser cronometrada utilizando timeit.timeit(). De forma semelhante ao exemplo anterior, o parâmetro number especifica o número de execuções da função (15 vezes). O tempo médio de execução é então calculado dividindo-se o tempo total pelo número de execuções.

Esse método é mais limpo e mais eficiente para benchmarking de funções reais, além de evitar a sobrecarga de avaliar código a partir de uma string.

123456789
import timeit import numpy as np code_snippet = 'np.array([x ** 2 for x in range(1000000)])' iterations = 15 execution_time = timeit.timeit(code_snippet, number=iterations) average_time = execution_time / iterations print(f'Average execution time: {average_time:.6f} seconds')
copy

Ops, ocorreu o seguinte erro: NameError: name 'np' is not defined. O erro ocorre porque timeit.timeit() executa o código de forma isolada, portanto não tem acesso ao numpy a menos que você o importe explicitamente no argumento setup:

# Import numpy in timeit's environment
setup = 'import numpy as np'  
execution_time = timeit.timeit(code_snippet, setup=setup, number=iterations)

Utilizar funções é mais limpo, reduz erros e não exige o gerenciamento de imports externos por meio de uma string setup.

Aprimorando a Medição de Desempenho com Decorators

Aplicar a mesma lógica de temporização a várias funções é uma prática comum, e um decorator oferece uma maneira limpa e eficiente de implementar isso sem repetir código.

Cada vez que uma função é chamada, ela é executada normalmente, mas com benchmarking integrado. Decorators apresentam diversas vantagens: aumentam a reutilização ao aplicar a mesma lógica em várias funções, melhoram a clareza ao separar a lógica de temporização da funcionalidade principal e permitem personalização, como ajustar o número de iterações ou adicionar métricas adicionais para análise de desempenho.

123456789101112131415161718192021
import timeit # Decorator to time the execution of a function def timeit_decorator(number=1): def decorator(func): def wrapper(*args, **kwargs): # Measure time with timeit total_time = timeit.timeit(lambda: func(*args, **kwargs), number=number) average_time = total_time / number print(f'{func.__name__} executed in {average_time:.6f} seconds (average over {number} runs)') return func(*args, **kwargs) return wrapper return decorator # Function to measure @timeit_decorator(number=30) def generate_squares(): return [x**2 for x in range(1000000)] # Calling the decorated function squares_array = generate_squares()
copy

Agora, sempre que uma função decorada com @timeit_decorator for chamada, seu desempenho será automaticamente medido e os resultados serão exibidos.

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 1. Capítulo 3

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

Suggested prompts:

Can you explain how decorators work in Python?

What are some other use cases for decorators besides timing functions?

How can I customize the timeit_decorator for different functions?

Awesome!

Completion rate improved to 7.69

bookMedindo o Desempenho de Funções

Deslize para mostrar o menu

Embora medir trechos de código baseados em strings possa ser suficiente em alguns casos, essa abordagem carece de flexibilidade. Utilizar o timeit com funções oferece uma maneira mais eficaz de medir o desempenho, e decoradores simplificam o processo de mensuração do desempenho de várias funções de forma limpa e modular.

Utilizando timeit com Funções

O timeit pode medir o desempenho de funções diretamente ao receber um callable (ou seja, uma função) em vez de uma string. Isso é mais flexível e legível do que usar strings, especialmente quando se deseja avaliar funções complexas.

1234567891011121314
import timeit import numpy as np # Function to test def generate_squares(): return np.array([x ** 2 for x in range(1000000)]) # Measure time using a callable (function) iterations = 15 execution_time = timeit.timeit(generate_squares, number=iterations) # Calculate average time per run average_time = execution_time / iterations print(f'Average execution time: {average_time:.6f} seconds')
copy

Passa-se generate_squares como a função (callable) a ser cronometrada utilizando timeit.timeit(). De forma semelhante ao exemplo anterior, o parâmetro number especifica o número de execuções da função (15 vezes). O tempo médio de execução é então calculado dividindo-se o tempo total pelo número de execuções.

Esse método é mais limpo e mais eficiente para benchmarking de funções reais, além de evitar a sobrecarga de avaliar código a partir de uma string.

123456789
import timeit import numpy as np code_snippet = 'np.array([x ** 2 for x in range(1000000)])' iterations = 15 execution_time = timeit.timeit(code_snippet, number=iterations) average_time = execution_time / iterations print(f'Average execution time: {average_time:.6f} seconds')
copy

Ops, ocorreu o seguinte erro: NameError: name 'np' is not defined. O erro ocorre porque timeit.timeit() executa o código de forma isolada, portanto não tem acesso ao numpy a menos que você o importe explicitamente no argumento setup:

# Import numpy in timeit's environment
setup = 'import numpy as np'  
execution_time = timeit.timeit(code_snippet, setup=setup, number=iterations)

Utilizar funções é mais limpo, reduz erros e não exige o gerenciamento de imports externos por meio de uma string setup.

Aprimorando a Medição de Desempenho com Decorators

Aplicar a mesma lógica de temporização a várias funções é uma prática comum, e um decorator oferece uma maneira limpa e eficiente de implementar isso sem repetir código.

Cada vez que uma função é chamada, ela é executada normalmente, mas com benchmarking integrado. Decorators apresentam diversas vantagens: aumentam a reutilização ao aplicar a mesma lógica em várias funções, melhoram a clareza ao separar a lógica de temporização da funcionalidade principal e permitem personalização, como ajustar o número de iterações ou adicionar métricas adicionais para análise de desempenho.

123456789101112131415161718192021
import timeit # Decorator to time the execution of a function def timeit_decorator(number=1): def decorator(func): def wrapper(*args, **kwargs): # Measure time with timeit total_time = timeit.timeit(lambda: func(*args, **kwargs), number=number) average_time = total_time / number print(f'{func.__name__} executed in {average_time:.6f} seconds (average over {number} runs)') return func(*args, **kwargs) return wrapper return decorator # Function to measure @timeit_decorator(number=30) def generate_squares(): return [x**2 for x in range(1000000)] # Calling the decorated function squares_array = generate_squares()
copy

Agora, sempre que uma função decorada com @timeit_decorator for chamada, seu desempenho será automaticamente medido e os resultados serão exibidos.

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 1. Capítulo 3
some-alt