krateng/maloja

View on GitHub
maloja/dev/profiler.py

Summary

Maintainability
A
2 hrs
Test Coverage
import os

import cProfile, pstats
import time

from doreah.logging import log

from ..pkg_global.conf import data_dir




FULL_PROFILE = False
SINGLE_CALLS = False
# only save the last single call instead of adding up all calls
# of that function for more representative performance result

if not SINGLE_CALLS:
    profilers = {}
    times = {}

def profile(func):

    realfunc = func
    while hasattr(realfunc, '__innerfunc__'):
        realfunc = realfunc.__innerfunc__

    def newfunc(*args,**kwargs):

        starttime = time.time()

        if FULL_PROFILE:
            benchmarkfolder = data_dir['logs']("benchmarks")
            os.makedirs(benchmarkfolder,exist_ok=True)
            if SINGLE_CALLS:
                localprofiler = cProfile.Profile()
            else:
                localprofiler = profilers.setdefault(realfunc,cProfile.Profile())
            localprofiler.enable()

        result = func(*args,**kwargs)

        if FULL_PROFILE:
            localprofiler.disable()

        seconds = time.time() - starttime

        if not SINGLE_CALLS:
            times.setdefault(realfunc,[]).append(seconds)

        if SINGLE_CALLS:
            log(f"Executed {realfunc.__name__} ({args}, {kwargs}) in {seconds:.3f}s",module="debug_performance")
        else:
            log(f"Executed {realfunc.__name__} ({args}, {kwargs}) in {seconds:.3f}s (Average: { sum(times[realfunc])/len(times[realfunc]):.3f}s)",module="debug_performance")

        if FULL_PROFILE:
            targetfilename = os.path.join(benchmarkfolder,f"{realfunc.__name__}.stats")
            try:
                pstats.Stats(localprofiler).dump_stats(targetfilename)
                log(f"Saved benchmark as {targetfilename}")
            except Exception:
                log(f"Failed to save benchmark as {targetfilename}")

        return result

    return newfunc