Source code for dipy.core.profile

"""Class for profiling cython code"""

import os
import subprocess

from dipy.testing.decorators import warning_for_keywords
from dipy.utils.optpkg import optional_package

cProfile, _, _ = optional_package("cProfile")
pstats, _, _ = optional_package(
    "pstats",
    trip_msg="pstats is not installed.  It is "
    "part of the python-profiler package in "
    "Debian/Ubuntu",
)


[docs] class Profiler: """Profile python/cython files or functions If you are profiling cython code you need to add # cython: profile=True on the top of your .pyx file and for the functions that you do not want to profile you can use this decorator in your cython files @cython.profile(False) Parameters ---------- caller : file or function call args : function arguments Attributes ---------- stats : function, stats.print_stats(10) will prin the 10 slower functions Examples -------- from dipy.core.profile import Profiler import numpy as np p=Profiler(np.sum,np.random.rand(1000000,3)) fname='test.py' p=Profiler(fname) p.print_stats(10) p.print_stats('det') References ---------- https://docs.cython.org/src/tutorial/profiling_tutorial.html https://docs.python.org/library/profile.html https://github.com/rkern/line_profiler """ def __init__(self, *args, call=None): # Delay import until use of class instance. We were getting some very # odd build-as-we-go errors running tests and documentation otherwise import pyximport pyximport.install() try: ext = os.path.splitext(call)[1].lower() print("ext", ext) if ext in (".py", ".pyx"): # python/cython file print("profiling python/cython file ...") subprocess.call( ["python3", "-m", "cProfile", "-o", "profile.prof", call] ) s = pstats.Stats("profile.prof") stats = s.strip_dirs().sort_stats("time") self.stats = stats except Exception: print("profiling function call ...") self.args = args self.call = call cProfile.runctx( "self._profile_function()", globals(), locals(), "profile.prof" ) s = pstats.Stats("profile.prof") stats = s.strip_dirs().sort_stats("time") self.stats = stats def _profile_function(self): self.call(*self.args)
[docs] @warning_for_keywords() def print_stats(self, *, N=10): """Print stats for profiling You can use it in all different ways developed in pstats for example print_stats(10) will give you the 10 slowest calls or print_stats('function_name') will give you the stats for all the calls with name 'function_name' Parameters ---------- N : stats.print_stats argument """ self.stats.print_stats(N)