369-370 #ˆl–Ãa¾”d*j"TÚ�zã@¸Ø”Å£Á ƒq–›À¿ÃÉ#! /usr/bin/python3.9 """Python interface for the 'lsprof' profiler. Compatible with the 'profile' module. """ __all__ = ["run", "runctx", "Profile"] import _lsprof import io import profile as _pyprofile # ____________________________________________________________ # Simple interface def run(statement, filename=None, sort=-1): return _pyprofile._Utils(Profile).run(statement, filename, sort) def runctx(statement, globals, locals, filename=None, sort=-1): return _pyprofile._Utils(Profile).runctx(statement, globals, locals, filename, sort) run.__doc__ = _pyprofile.run.__doc__ runctx.__doc__ = _pyprofile.runctx.__doc__ # ____________________________________________________________ class Profile(_lsprof.Profiler): """Profile(timer=None, timeunit=None, subcalls=True, builtins=True) Builds a profiler object using the specified timer function. The default timer is a fast built-in one based on real time. For custom timer functions returning integers, timeunit can be a float specifying a scale (i.e. how long each integer unit is, in seconds). """ # Most of the functionality is in the base class. # This subclass only adds convenient and backward-compatible methods. def print_stats(self, sort=-1): import pstats pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats() def dump_stats(self, file): import marshal with open(file, 'wb') as f: self.create_stats() marshal.dump(self.stats, f) def create_stats(self): self.disable() self.snapshot_stats() def snapshot_stats(self): entries = self.getstats() self.stats = {} callersdicts = {} # call information for entry in entries: func = label(entry.code) nc = entry.callcount # ncalls column of pstats (before '/') cc = nc - entry.reccallcount # ncalls column of pstats (after '/') tt = entry.inlinetime # tottime column of pstats ct = entry.totaltime # cumtime column of pstats callers = {} callersdicts[id(entry.code)] = callers self.stats[func] = cc, nc, tt, ct, callers # subcall information for entry in entries: if entry.calls: func = label(entry.code) for subentry in entry.calls: try: callers = callersdicts[id(subentry.code)] except KeyError: continue nc = subentry.callcount cc = nc - subentry.reccallcount tt = subentry.inlinetime ct = subentry.totaltime if func in callers: prev = callers[func] nc += prev[0] cc += prev[1] tt += prev[2] ct += prev[3] callers[func] = nc, cc, tt, ct # The following two methods can be called by clients to use # a profiler to profile a statement, given as a string. def run(self, cmd): import __main__ dict = __main__.__dict__ return self.runctx(cmd, dict, dict) def runctx(self, cmd, globals, locals): self.enable() try: exec(cmd, globals, locals) finally: self.disable() return self # This method is more useful to profile a single function call. def runcall(self, func, /, *args, **kw): self.enable() try: return func(*args, **kw) finally: self.disable() def __enter__(self): self.enable() return self def __exit__(self, *exc_info): self.disable() # ____________________________________________________________ def label(code): if isinstance(code, str): return ('~', 0, code) # b