4
4
# instead of just the Stats object
7
9
from _lsprof import Profiler, profiler_entry, profiler_subentry
9
11
__all__ = ['profile', 'Stats']
15
def _thread_profile(f, *args, **kwds):
16
# we lose the first profile point for a new thread in order to trampoline
17
# a new Profile object into place
19
thr = thread.get_ident()
20
_g_threadmap[thr] = p = Profiler()
21
# this overrides our sys.setprofile hook:
22
p.enable(subcalls=True)
11
25
def profile(f, *args, **kwds):
12
26
"""XXX docstring"""
14
29
p.enable(subcalls=True)
30
threading.setprofile(_thread_profile)
16
32
ret = f(*args, **kwds)
19
return ret,Stats(p.getstats())
35
for pp in _g_threadmap.values():
37
threading.setprofile(None)
40
for tid, pp in _g_threadmap.items():
41
threads[tid] = Stats(pp.getstats(), {})
43
return ret, Stats(p.getstats(), threads)
22
46
class Stats(object):
23
47
"""XXX docstring"""
25
def __init__(self, data):
49
def __init__(self, data, threads):
51
self.threads = threads
28
53
def sort(self, crit="inlinetime"):
29
54
"""XXX docstring"""