Medindo 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.
1234567891011121314import 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')
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.
123456789import 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')
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.
123456789101112131415161718192021import 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()
Agora, sempre que uma função decorada com @timeit_decorator for chamada, seu desempenho será automaticamente medido e os resultados serão exibidos.
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo
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
Medindo 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.
1234567891011121314import 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')
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.
123456789import 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')
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.
123456789101112131415161718192021import 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()
Agora, sempre que uma função decorada com @timeit_decorator for chamada, seu desempenho será automaticamente medido e os resultados serão exibidos.
Obrigado pelo seu feedback!