Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Medición del Rendimiento de Funciones | Comprensión y Medición del Rendimiento
Técnicas de Optimización en Python

bookMedición del Rendimiento de Funciones

Aunque medir fragmentos de código basados en cadenas puede ser suficiente en ocasiones, este enfoque carece de flexibilidad. Utilizar timeit con funciones proporciona una forma más eficaz de medir el rendimiento, y los decoradores simplifican el proceso de medir el rendimiento de múltiples funciones de manera limpia y modular.

Uso de timeit con funciones

timeit puede medir el rendimiento de las funciones directamente pasando un callable (es decir, una función) en lugar de una cadena. Esto es más flexible y legible que usar cadenas, especialmente cuando se desea evaluar el rendimiento de funciones complejas.

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

Pasamos generate_squares como la función (callable) a medir utilizando timeit.timeit(). De manera similar a lo anterior, el parámetro number especifica la cantidad de veces que se ejecutará la función (15 veces). El tiempo promedio de ejecución se calcula dividiendo el tiempo total entre el número de ejecuciones.

Este método es más limpio y eficiente para evaluar funciones reales, y evita la sobrecarga de evaluar código desde una cadena de texto.

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

Ups, obtuvimos el siguiente error: NameError: name 'np' is not defined. El error ocurre porque timeit.timeit() ejecuta el código de forma aislada, por lo que no tiene acceso a numpy a menos que lo importes explícitamente en el argumento setup:

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

Utilizar funciones es más limpio, reduce errores y no requiere gestionar importaciones externas mediante una cadena setup.

Mejora de la medición del rendimiento con decoradores

Aplicar la misma lógica de temporización a varias funciones es una práctica común, y un decorador proporciona una forma limpia y eficiente de implementarlo sin repetir código.

Cada vez que se llama a una función, se ejecuta normalmente, pero con la evaluación de rendimiento integrada. Los decoradores ofrecen varias ventajas: mejoran la reutilización al aplicar la misma lógica en varias funciones, aumentan la claridad al separar la lógica de temporización de la funcionalidad principal y permiten la personalización, como ajustar el número de iteraciones o añadir métricas adicionales para el análisis del rendimiento.

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

Ahora, cada vez que se llama a una función decorada con @timeit_decorator, su rendimiento será medido automáticamente y los resultados se mostrarán.

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 1. Capítulo 3

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Awesome!

Completion rate improved to 7.69

bookMedición del Rendimiento de Funciones

Desliza para mostrar el menú

Aunque medir fragmentos de código basados en cadenas puede ser suficiente en ocasiones, este enfoque carece de flexibilidad. Utilizar timeit con funciones proporciona una forma más eficaz de medir el rendimiento, y los decoradores simplifican el proceso de medir el rendimiento de múltiples funciones de manera limpia y modular.

Uso de timeit con funciones

timeit puede medir el rendimiento de las funciones directamente pasando un callable (es decir, una función) en lugar de una cadena. Esto es más flexible y legible que usar cadenas, especialmente cuando se desea evaluar el rendimiento de funciones complejas.

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

Pasamos generate_squares como la función (callable) a medir utilizando timeit.timeit(). De manera similar a lo anterior, el parámetro number especifica la cantidad de veces que se ejecutará la función (15 veces). El tiempo promedio de ejecución se calcula dividiendo el tiempo total entre el número de ejecuciones.

Este método es más limpio y eficiente para evaluar funciones reales, y evita la sobrecarga de evaluar código desde una cadena de texto.

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

Ups, obtuvimos el siguiente error: NameError: name 'np' is not defined. El error ocurre porque timeit.timeit() ejecuta el código de forma aislada, por lo que no tiene acceso a numpy a menos que lo importes explícitamente en el argumento setup:

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

Utilizar funciones es más limpio, reduce errores y no requiere gestionar importaciones externas mediante una cadena setup.

Mejora de la medición del rendimiento con decoradores

Aplicar la misma lógica de temporización a varias funciones es una práctica común, y un decorador proporciona una forma limpia y eficiente de implementarlo sin repetir código.

Cada vez que se llama a una función, se ejecuta normalmente, pero con la evaluación de rendimiento integrada. Los decoradores ofrecen varias ventajas: mejoran la reutilización al aplicar la misma lógica en varias funciones, aumentan la claridad al separar la lógica de temporización de la funcionalidad principal y permiten la personalización, como ajustar el número de iteraciones o añadir métricas adicionales para el análisis del rendimiento.

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

Ahora, cada vez que se llama a una función decorada con @timeit_decorator, su rendimiento será medido automáticamente y los resultados se mostrarán.

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 1. Capítulo 3
some-alt