Skip to content

Instantly share code, notes, and snippets.

@vlad-bezden
Last active November 9, 2022 16:05
Show Gist options
  • Save vlad-bezden/b19352b488b76dbdc83e687e782802d1 to your computer and use it in GitHub Desktop.
Save vlad-bezden/b19352b488b76dbdc83e687e782802d1 to your computer and use it in GitHub Desktop.
Function decorator to calculate function execution time for either sync or async functions
"""Helper module to calculate function execution time."""
import logging
from functools import wraps
from time import perf_counter
from typing import Any, Awaitable, Callable, Coroutine, ParamSpec, TypeVar
FORMAT = "%(asctime)s %(message)s"
logging.basicConfig(level=logging.DEBUG, format=FORMAT)
logger = logging.getLogger(__name__)
T = TypeVar("T")
P = ParamSpec("P")
def timer(func: Callable[P, T]) -> Callable[P, T]:
"""Synchronous timer function decorator."""
@wraps(func)
def wrapper_timer(*args: P.args, **kwargs: P.kwargs) -> T:
start = perf_counter()
try:
return func(*args, **kwargs)
finally:
logger.debug(
"'%s' exec time: %s sec", func.__name__, f"{perf_counter() - start:.2f}"
)
return wrapper_timer
def async_timer(func: Callable[P, Awaitable[T]]) -> Callable[P, Coroutine[Any, Any, T]]:
"""Asynchronous timer function decorator."""
@wraps(func)
async def wrapper_timer(*args: P.args, **kwargs: P.kwargs) -> T:
start = perf_counter()
try:
return await func(*args, **kwargs)
finally:
logger.debug(
"'%s' exec time: %s sec",
func.__name__,
f"{perf_counter() - start:.2f}",
)
return wrapper_timer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment