Decorator for Timing Functions
Measure and log execution time of functions with a decorator
0
Python Code
import time
import functools
import logging
from typing import Any, Callable
import asyncio
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
def timer(func: Callable) -> Callable:
"""Decorator to measure and log function execution time."""
@functools.wraps(func)
def wrapper_sync(*args, **kwargs) -> Any:
start = time.perf_counter()
try:
result = func(*args, **kwargs)
return result
finally:
end = time.perf_counter()
logging.info(f"{func.__name__} took {end - start:.4f} seconds")
@functools.wraps(func)
async def wrapper_async(*args, **kwargs) -> Any:
start = time.perf_counter()
try:
result = await func(*args, **kwargs)
return result
finally:
end = time.perf_counter()
logging.info(f"{func.__name__} took {end - start:.4f} seconds")
if asyncio.iscoroutinefunction(func):
return wrapper_async
return wrapper_sync
class TimerContext:
"""Context manager for timing code blocks"""
def __init__(self, name: str = "Code block"):
self.name = name
def __enter__(self):
self.start = time.perf_counter()
return self
def __exit__(self, *args):
self.end = time.perf_counter()
logging.info(f"{self.name} took {self.end - self.start:.4f} seconds")
# Usage
@timer
def slow_function():
time.sleep(1)
return "Done"
@timer
async def async_slow():
await asyncio.sleep(1)
return "Async done"
with TimerContext("Complex operation"):
time.sleep(0.5)
time.sleep(0.3)
Explanation
This timing module demonstrates Python decorators, context managers, and async support. The @timer decorator automatically measures execution time for both sync and async functions. The TimerContext class allows timing specific code blocks.