Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
tree_dict : dict
Tree of nested dictionaries representing the profile call tree.
"""
# recursive_seen prevents us from repeatedly traversing
# recursive structures. only want to show the first set.
if recursive_seen is None:
recursive_seen = set()
d = {}
d['name'] = node.name
d['filename'] = node.filename
d['directory'] = node.directory
if isinstance(node, pstatsloader.PStatRow):
d['calls'] = node.calls
d['recursive'] = node.recursive
d['local'] = node.local
d['localPer'] = node.localPer
d['cumulative'] = node.cummulative
d['cumulativePer'] = node.cummulativePer
d['line_number'] = node.lineno
recursive_seen.add(node)
if parent:
# figure out the size of this node. This is an arbitrary value
# but it's important that the child size is no larger
# than the parent size.
if isinstance(parent, pstatsloader.PStatGroup):
if parent.cummulative:
profile stats table beneath the profile visualization.
Parameters
----------
filename : str
Name of profiling output as made by Python's built-in profilers.
"""
time_fmt = '{0:>12.6g}'
loader = pstatsloader.PStatsLoader(filename)
rows = []
for r in loader.rows.values():
if isinstance(r, pstatsloader.PStatRow):
calls_value = r.recursive
if r.recursive > r.calls:
calls_str = '{0}/{1}'.format(r.recursive, r.calls)
else:
calls_str = str(r.calls)
tottime = r.local
tottime_str = time_fmt.format(tottime)
tottime_percall = r.localPer
tottime_percall_str = time_fmt.format(tottime_percall)
cumtime = r.cummulative
cumtime_str = time_fmt.format(cumtime)
cumtime_percall = r.cummulativePer
cumtime_percall_str = time_fmt.format(cumtime_percall)
file_line_func = '{0}:{1}({2})'.format(r.filename,
r.lineno,
r.name)
if d['children']:
# make a "child" that represents the internal time of this function
children_sum = sum(c['size'] for c in d['children'])
if children_sum > d['size']:
for child in d['children']:
child['size'] = child['size'] / children_sum * d['size']
elif children_sum < d['size']:
d_internal = {'name': node.name,
'filename': node.filename,
'directory': node.directory,
'size': d['size'] - children_sum}
if isinstance(node, pstatsloader.PStatRow):
d_internal['calls'] = node.calls
d_internal['recursive'] = node.recursive
d_internal['local'] = node.local
d_internal['localPer'] = node.localPer
d_internal['cumulative'] = node.cummulative
d_internal['cumulativePer'] = node.cummulativePer
d_internal['line_number'] = node.lineno
d['children'].append(d_internal)
else:
# there were no non-recursive children so get rid of the
# children list.
del d['children']
if node in recursive_seen:
# remove this node from the set so it doesn't interfere if this
def load( self, stats ):
"""Build a squaremap-compatible model from a pstats class"""
rows = self.rows
for func, raw in stats.items():
try:
rows[func] = row = PStatRow( func,raw )
except ValueError as err:
log.info( 'Null row: %s', func )
for row in rows.values():
row.weave( rows )
return self.find_root( rows )
def calculate_totals( self, children, local_children=None ):
"""Calculate our cummulative totals from children and/or local children"""
for field,local_field in (('recursive','calls'),('cummulative','local')):
values = []
for child in children:
if isinstance( child, PStatGroup ) or not self.LOCAL_ONLY:
values.append( getattr( child, field, 0 ) )
elif isinstance( child, PStatRow ) and self.LOCAL_ONLY:
values.append( getattr( child, local_field, 0 ) )
value = sum( values )
setattr( self, field, value )
if self.recursive:
self.cummulativePer = self.cummulative/float(self.recursive)
else:
self.recursive = 0
if local_children:
for field in ('local','calls'):
value = sum([ getattr( child, field, 0 ) for child in children] )
setattr( self, field, value )
if self.calls:
self.localPer = self.local / self.calls
else:
self.local = 0
self.calls = 0