1f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake"""High-perfomance logging profiler, mostly written in C.""" 2f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 3f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drakeimport _hotshot 4f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drakefrom _hotshot import ProfilerError 5f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 6ab68a3dc6fbf0dd9e1737516aa9bf75485842cdeAlexandre Vassalottifrom warnings import warnpy3k as _warnpy3k 7ab68a3dc6fbf0dd9e1737516aa9bf75485842cdeAlexandre Vassalotti_warnpy3k("The 'hotshot' module is not supported in 3.x, " 8ab68a3dc6fbf0dd9e1737516aa9bf75485842cdeAlexandre Vassalotti "use the 'profile' module instead.", stacklevel=2) 9f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 10f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drakeclass Profile: 11f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake def __init__(self, logfn, lineevents=0, linetimings=1): 12f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake self.lineevents = lineevents and 1 or 0 13f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake self.linetimings = (linetimings and lineevents) and 1 or 0 14f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake self._prof = p = _hotshot.profiler( 15f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake logfn, self.lineevents, self.linetimings) 16f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 1734f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake # Attempt to avoid confusing results caused by the presence of 1834f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake # Python wrappers around these functions, but only if we can 1934f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake # be sure the methods have not been overridden or extended. 2034f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake if self.__class__ is Profile: 2134f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake self.close = p.close 2234f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake self.start = p.start 2334f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake self.stop = p.stop 2434f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake self.addinfo = p.addinfo 2534f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake 26f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake def close(self): 2734f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """Close the logfile and terminate the profiler.""" 28f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake self._prof.close() 29f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 30302e2bb81b462f2664b71da9f35c2969df8a330eFred Drake def fileno(self): 31302e2bb81b462f2664b71da9f35c2969df8a330eFred Drake """Return the file descriptor of the profiler's log file.""" 32302e2bb81b462f2664b71da9f35c2969df8a330eFred Drake return self._prof.fileno() 33302e2bb81b462f2664b71da9f35c2969df8a330eFred Drake 34f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake def start(self): 3534f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """Start the profiler.""" 36f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake self._prof.start() 37f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 38f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake def stop(self): 3934f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """Stop the profiler.""" 40f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake self._prof.stop() 41f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 42165b2cc2bdf17b1cb4b695f2438e611313d99c1cFred Drake def addinfo(self, key, value): 4334f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """Add an arbitrary labelled value to the profile log.""" 44165b2cc2bdf17b1cb4b695f2438e611313d99c1cFred Drake self._prof.addinfo(key, value) 45165b2cc2bdf17b1cb4b695f2438e611313d99c1cFred Drake 46f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake # These methods offer the same interface as the profile.Profile class, 47f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake # but delegate most of the work to the C implementation underneath. 48f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 49f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake def run(self, cmd): 5034f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """Profile an exec-compatible string in the script 5134f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake environment. 5234f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake 5334f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake The globals from the __main__ module are used as both the 5434f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake globals and locals for the script. 5534f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """ 56f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake import __main__ 57f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake dict = __main__.__dict__ 58f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake return self.runctx(cmd, dict, dict) 59f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 60f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake def runctx(self, cmd, globals, locals): 6134f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """Evaluate an exec-compatible string in a specific 6234f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake environment. 6334f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake 6434f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake The string is compiled before profiling begins. 6534f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """ 66f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake code = compile(cmd, "<string>", "exec") 67f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake self._prof.runcode(code, globals, locals) 68f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake return self 69f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake 70f019324b5c7a77f4983c06e5abb03b7751ea7305Fred Drake def runcall(self, func, *args, **kw): 7134f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """Profile a single call of a callable. 7234f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake 7334f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake Additional positional and keyword arguments may be passed 7434f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake along; the result of the call is returned, and exceptions are 758d496add74530767cad3aa8b5b371b9a7f0b8498Martin Panter allowed to propagate cleanly, while ensuring that profiling is 7634f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake disabled on the way out. 7734f300a53ea4e5a8396129b171e6d97bf4e4680dFred Drake """ 78e7d8a78b8e6d60d3d75f9dc0599288d0101fff05Fred Drake return self._prof.runcall(func, args, kw) 79