Source code for pathsim.utils.debugging

########################################################################################
##
##                           DEBUGGING AND EVALUATION TOOLS  
##                                (utils/debugging.py)
##
##                                  Milan Rother 2024
##
########################################################################################

# IMPORTS ==============================================================================

import numpy as np

from collections import deque
from contextlib import ContextDecorator
from functools import wraps
from time import perf_counter

try:
    import cProfile, pstats
    PROFILE_AVAILABLE = True
except ImportError:
    PROFILE_AVAILABLE = False


# CLASSES ==============================================================================

[docs] class Timer: """Context manager that times the execution time of the code inside of the context in 'ms' for debugging purposes. Example ------- .. code-block:: python #time the code within the context with Timer() as T: complicated_function() #print the runtime print(T.time) Parameters ---------- verbose : bool flag for verbose output """ def __init__(self, verbose=True): self.verbose = verbose def __enter__(self): self.start = perf_counter() return self def __exit__(self, type, value, traceback): self.time = perf_counter() - self.start self.readout = f"{self.time*1e3:.3f}ms" if self.verbose: print("runtime:", self.readout)
[docs] def timer(func): """Shows the execution time in milliseconds of the function object passed for debugging purposes Parameters ---------- func : callable function to track execution time of """ @wraps(func) def wrap_func(*args, **kwargs): t1 = perf_counter() result = func(*args, **kwargs) t2 = perf_counter() print(f"Function '{func.__name__!r}' executed in {(t2 - t1)*1e3:.2f}ms") return result return wrap_func
[docs] class Profiler(ContextDecorator): """Context manager for easy code profiling Example ------- .. code-block:: python #profile the code within the context with Profiler(): complicated_function() Parameters ---------- top_n : int track top n function calls sort_by : str method to sort function cally by """ def __init__(self, top_n=50, sort_by="cumulative"): self.top_n = top_n self.sort_by = sort_by self.profiler = cProfile.Profile() def __enter__(self): self.profiler.enable() return self def __exit__(self, *exc): self.profiler.disable() stats = pstats.Stats(self.profiler) stats.strip_dirs() stats.sort_stats(self.sort_by) stats.print_stats(self.top_n) return False