summary.py (5713B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\pympler\summary.py 2 from __future__ import print_function 3 import re 4 import sys 5 import types 6 from pympler.util import stringutils 7 try: 8 from sys import getsizeof as _getsizeof 9 except ImportError: 10 from pympler.asizeof import flatsize 11 _getsizeof = flatsize 12 13 representations = {} 14 15 def _init_representations(): 16 global representations 17 if sys.hexversion < 33816576: 18 classobj = [lambda c: 'classobj(%s)' % repr(c)] 19 representations[types.ClassType] = classobj 20 instance = [lambda f: 'instance(%s)' % repr(f.__class__)] 21 representations[types.InstanceType] = instance 22 instancemethod = [lambda i: 'instancemethod (%s)' % repr(i.im_func), lambda i: 'instancemethod (%s, %s)' % (repr(i.im_class), repr(i.im_func))] 23 representations[types.MethodType] = instancemethod 24 frame = [lambda f: 'frame (codename: %s)' % f.f_code.co_name, lambda f: 'frame (codename: %s, codeline: %s)' % (f.f_code.co_name, f.f_code.co_firstlineno), lambda f: 'frame (codename: %s, filename: %s, codeline: %s)' % (f.f_code.co_name, f.f_code.co_filename, f.f_code.co_firstlineno)] 25 representations[types.FrameType] = frame 26 _dict = [lambda d: str(type(d)), lambda d: 'dict, len=%s' % len(d)] 27 representations[dict] = _dict 28 function = [lambda f: 'function (%s)' % f.__name__, lambda f: 'function (%s.%s)' % (f.__module, f.__name__)] 29 representations[types.FunctionType] = function 30 _list = [lambda l: str(type(l)), lambda l: 'list, len=%s' % len(l)] 31 representations[list] = _list 32 module = [lambda m: 'module(%s)' % m.__name__] 33 representations[types.ModuleType] = module 34 _set = [lambda s: str(type(s)), lambda s: 'set, len=%s' % len(s)] 35 representations[set] = _set 36 37 38 _init_representations() 39 40 def summarize(objects): 41 count = {} 42 total_size = {} 43 for o in objects: 44 otype = _repr(o) 45 if otype in count: 46 count[otype] += 1 47 total_size[otype] += _getsizeof(o) 48 else: 49 count[otype] = 1 50 total_size[otype] = _getsizeof(o) 51 52 rows = [] 53 for otype in count: 54 rows.append([otype, count[otype], total_size[otype]]) 55 56 return rows 57 58 59 def get_diff(left, right): 60 res = [] 61 for row_r in right: 62 found = False 63 for row_l in left: 64 if row_r[0] == row_l[0]: 65 res.append([row_r[0], row_r[1] - row_l[1], row_r[2] - row_l[2]]) 66 found = True 67 68 if not found: 69 res.append(row_r) 70 71 for row_l in left: 72 found = False 73 for row_r in right: 74 if row_l[0] == row_r[0]: 75 found = True 76 77 if not found: 78 res.append([row_l[0], -row_l[1], -row_l[2]]) 79 80 return res 81 82 83 def format_(rows, limit = 15, sort = 'size', order = 'descending'): 84 localrows = [] 85 for row in rows: 86 localrows.append(list(row)) 87 88 sortby = ['type', '#', 'size'] 89 if sort not in sortby: 90 raise ValueError('invalid sort, should be one of' + str(sortby)) 91 orders = ['ascending', 'descending'] 92 if order not in orders: 93 raise ValueError('invalid order, should be one of' + str(orders)) 94 if sortby.index(sort) == 0: 95 if order == 'ascending': 96 localrows.sort(key=lambda x: _repr(x[0])) 97 elif order == 'descending': 98 localrows.sort(key=lambda x: _repr(x[0]), reverse=True) 99 elif order == 'ascending': 100 localrows.sort(key=lambda x: x[sortby.index(sort)]) 101 elif order == 'descending': 102 localrows.sort(key=lambda x: x[sortby.index(sort)], reverse=True) 103 localrows = localrows[0:limit] 104 for row in localrows: 105 row[2] = stringutils.pp(row[2]) 106 107 localrows.insert(0, ['types', '# objects', 'total size']) 108 return _format_table(localrows) 109 110 111 def _format_table(rows, header = True): 112 border = '=' 113 vdelim = ' | ' 114 padding = 1 115 justify = 'right' 116 justify = {'left': str.ljust, 117 'center': str.center, 118 'right': str.rjust}[justify.lower()] 119 cols = zip(*rows) 120 colWidths = [ max([ len(str(item)) + 2 * padding for item in col ]) for col in cols ] 121 borderline = vdelim.join([ w * border for w in colWidths ]) 122 for row in rows: 123 yield vdelim.join([ justify(str(item), width) for item, width in zip(row, colWidths) ]) 124 if header: 125 yield borderline 126 header = False 127 128 129 def print_(rows, limit = 15, sort = 'size', order = 'descending'): 130 for line in format_(rows, limit=limit, sort=sort, order=order): 131 print(line) 132 133 134 type_prefix = re.compile("^<type '") 135 address = re.compile(' at 0x[0-9a-f]+') 136 type_suffix = re.compile("'>$") 137 138 def _repr(o, verbosity = 1): 139 res = '' 140 t = type(o) 141 if verbosity == 0 or t not in representations: 142 res = str(t) 143 else: 144 verbosity -= 1 145 if len(representations[t]) < verbosity: 146 verbosity = len(representations[t]) - 1 147 res = representations[t][verbosity](o) 148 res = address.sub('', res) 149 res = type_prefix.sub('', res) 150 res = type_suffix.sub('', res) 151 return res 152 153 154 def _traverse(summary, function, *args): 155 function(summary, *args) 156 for row in summary: 157 function(row, *args) 158 for item in row: 159 function(item, *args) 160 161 162 def _subtract(summary, o): 163 found = False 164 row = [_repr(o), 1, _getsizeof(o)] 165 for r in summary: 166 if r[0] == row[0]: 167 r[1], r[2] = r[1] - row[1], r[2] - row[2] 168 found = True 169 170 if not found: 171 summary.append([row[0], -row[1], -row[2]]) 172 return summary 173 174 175 def _sweep(summary): 176 return [ row for row in summary if row[2] != 0 or row[1] != 0 ]