1 | """High-perfomance logging profiler, mostly written in C."""
|
---|
2 |
|
---|
3 | import _hotshot
|
---|
4 | from _hotshot import ProfilerError
|
---|
5 |
|
---|
6 | from warnings import warnpy3k as _warnpy3k
|
---|
7 | _warnpy3k("The 'hotshot' module is not supported in 3.x, "
|
---|
8 | "use the 'profile' module instead.", stacklevel=2)
|
---|
9 |
|
---|
10 | class Profile:
|
---|
11 | def __init__(self, logfn, lineevents=0, linetimings=1):
|
---|
12 | self.lineevents = lineevents and 1 or 0
|
---|
13 | self.linetimings = (linetimings and lineevents) and 1 or 0
|
---|
14 | self._prof = p = _hotshot.profiler(
|
---|
15 | logfn, self.lineevents, self.linetimings)
|
---|
16 |
|
---|
17 | # Attempt to avoid confusing results caused by the presence of
|
---|
18 | # Python wrappers around these functions, but only if we can
|
---|
19 | # be sure the methods have not been overridden or extended.
|
---|
20 | if self.__class__ is Profile:
|
---|
21 | self.close = p.close
|
---|
22 | self.start = p.start
|
---|
23 | self.stop = p.stop
|
---|
24 | self.addinfo = p.addinfo
|
---|
25 |
|
---|
26 | def close(self):
|
---|
27 | """Close the logfile and terminate the profiler."""
|
---|
28 | self._prof.close()
|
---|
29 |
|
---|
30 | def fileno(self):
|
---|
31 | """Return the file descriptor of the profiler's log file."""
|
---|
32 | return self._prof.fileno()
|
---|
33 |
|
---|
34 | def start(self):
|
---|
35 | """Start the profiler."""
|
---|
36 | self._prof.start()
|
---|
37 |
|
---|
38 | def stop(self):
|
---|
39 | """Stop the profiler."""
|
---|
40 | self._prof.stop()
|
---|
41 |
|
---|
42 | def addinfo(self, key, value):
|
---|
43 | """Add an arbitrary labelled value to the profile log."""
|
---|
44 | self._prof.addinfo(key, value)
|
---|
45 |
|
---|
46 | # These methods offer the same interface as the profile.Profile class,
|
---|
47 | # but delegate most of the work to the C implementation underneath.
|
---|
48 |
|
---|
49 | def run(self, cmd):
|
---|
50 | """Profile an exec-compatible string in the script
|
---|
51 | environment.
|
---|
52 |
|
---|
53 | The globals from the __main__ module are used as both the
|
---|
54 | globals and locals for the script.
|
---|
55 | """
|
---|
56 | import __main__
|
---|
57 | dict = __main__.__dict__
|
---|
58 | return self.runctx(cmd, dict, dict)
|
---|
59 |
|
---|
60 | def runctx(self, cmd, globals, locals):
|
---|
61 | """Evaluate an exec-compatible string in a specific
|
---|
62 | environment.
|
---|
63 |
|
---|
64 | The string is compiled before profiling begins.
|
---|
65 | """
|
---|
66 | code = compile(cmd, "<string>", "exec")
|
---|
67 | self._prof.runcode(code, globals, locals)
|
---|
68 | return self
|
---|
69 |
|
---|
70 | def runcall(self, func, *args, **kw):
|
---|
71 | """Profile a single call of a callable.
|
---|
72 |
|
---|
73 | Additional positional and keyword arguments may be passed
|
---|
74 | along; the result of the call is returned, and exceptions are
|
---|
75 | allowed to propogate cleanly, while ensuring that profiling is
|
---|
76 | disabled on the way out.
|
---|
77 | """
|
---|
78 | return self._prof.runcall(func, args, kw)
|
---|