Decorator for Timing Functions

Python Intermediate 👁️ 2,875 views By system Added Just now

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.