Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: tools/binary_size/libsupersize/describe.py

Issue 2884283002: supersize: Fix diff logic for changed vs unchanged of groups (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/binary_size/diagnose_bloat.py ('k') | tools/binary_size/libsupersize/integration_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2017 The Chromium Authors. All rights reserved. 1 # Copyright 2017 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 """Methods for converting model objects to human-readable formats.""" 4 """Methods for converting model objects to human-readable formats."""
5 5
6 import datetime 6 import datetime
7 import itertools 7 import itertools
8 import time 8 import time
9 9
10 import models 10 import models
11 11
12 12
13 _DIFF_PREFIX_BY_STATUS = ['= ', '~ ', '+ ', '- ']
14
15
13 def _PrettySize(size): 16 def _PrettySize(size):
14 # Arbitrarily chosen cut-off. 17 # Arbitrarily chosen cut-off.
15 if abs(size) < 2000: 18 if abs(size) < 2000:
16 return '%d bytes' % size 19 return '%d bytes' % size
17 # Always show 3 digits. 20 # Always show 3 digits.
18 size /= 1024.0 21 size /= 1024.0
19 if abs(size) < 10: 22 if abs(size) < 10:
20 return '%.2fkb' % size 23 return '%.2fkb' % size
21 elif abs(size) < 100: 24 elif abs(size) < 100:
22 return '%.1fkb' % size 25 return '%.1fkb' % size
(...skipping 12 matching lines...) Expand all
35 if pss > 10: 38 if pss > 10:
36 return str(int(pss)) 39 return str(int(pss))
37 ret = str(round(pss, 1)) 40 ret = str(round(pss, 1))
38 if ret.endswith('.0'): 41 if ret.endswith('.0'):
39 ret = ret[:-2] 42 ret = ret[:-2]
40 if ret == '0' and pss: 43 if ret == '0' and pss:
41 ret = '~0' 44 ret = '~0'
42 return ret 45 return ret
43 46
44 47
45 def _DiffPrefix(diff, sym):
46 if diff.IsAdded(sym):
47 return '+ '
48 if diff.IsRemoved(sym):
49 return '- '
50 if sym.size:
51 return '~ '
52 return '= '
53
54
55 def _Divide(a, b): 48 def _Divide(a, b):
56 return float(a) / b if b else 0 49 return float(a) / b if b else 0
57 50
58 51
59 class Describer(object): 52 class Describer(object):
60 def __init__(self, verbose=False, recursive=False): 53 def __init__(self, verbose=False, recursive=False):
61 self.verbose = verbose 54 self.verbose = verbose
62 self.recursive = recursive 55 self.recursive = recursive
63 56
64 def _DescribeSectionSizes(self, section_sizes): 57 def _DescribeSectionSizes(self, section_sizes):
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 for index, s in enumerate(group): 125 for index, s in enumerate(group):
133 if group.IsBss() or not s.IsBss(): 126 if group.IsBss() or not s.IsBss():
134 running_total += s.pss 127 running_total += s.pss
135 running_percent = _Divide(running_total, total) 128 running_percent = _Divide(running_total, total)
136 for l in self._DescribeSymbol(s, single_line=all_groups): 129 for l in self._DescribeSymbol(s, single_line=all_groups):
137 if l[:4].isspace(): 130 if l[:4].isspace():
138 indent_size = 8 + len(indent_prefix) + len(diff_prefix) 131 indent_size = 8 + len(indent_prefix) + len(diff_prefix)
139 yield '{} {}'.format(' ' * indent_size, l) 132 yield '{} {}'.format(' ' * indent_size, l)
140 else: 133 else:
141 if is_diff: 134 if is_diff:
142 diff_prefix = _DiffPrefix(group, s) 135 diff_prefix = _DIFF_PREFIX_BY_STATUS[group.DiffStatus(s)]
143 yield '{}{}{:<4} {:>8} {:7} {}'.format( 136 yield '{}{}{:<4} {:>8} {:7} {}'.format(
144 indent_prefix, diff_prefix, str(index) + ')', 137 indent_prefix, diff_prefix, str(index) + ')',
145 _FormatPss(running_total), '({:.1%})'.format(running_percent), l) 138 _FormatPss(running_total), '({:.1%})'.format(running_percent), l)
146 139
147 if self.recursive and s.IsGroup(): 140 if self.recursive and s.IsGroup():
148 for l in self._DescribeSymbolGroupChildren(s, indent=indent + 1): 141 for l in self._DescribeSymbolGroupChildren(s, indent=indent + 1):
149 yield l 142 yield l
150 143
151 def _DescribeSymbolGroup(self, group): 144 def _DescribeSymbolGroup(self, group):
152 total_size = group.pss 145 total_size = group.pss
(...skipping 22 matching lines...) Expand all
175 _PrettySize(int(data_size)), _PrettySize(int(bss_size)), 168 _PrettySize(int(data_size)), _PrettySize(int(bss_size)),
176 _PrettySize(int(total_size))), 169 _PrettySize(int(total_size))),
177 'Number of unique paths: {}'.format(len(unique_paths)), 170 'Number of unique paths: {}'.format(len(unique_paths)),
178 '', 171 '',
179 'Index, Running Total, Section@Address, PSS', 172 'Index, Running Total, Section@Address, PSS',
180 '-' * 60 173 '-' * 60
181 ] 174 ]
182 children_desc = self._DescribeSymbolGroupChildren(group) 175 children_desc = self._DescribeSymbolGroupChildren(group)
183 return itertools.chain(header_desc, children_desc) 176 return itertools.chain(header_desc, children_desc)
184 177
178 def _DescribeDiffObjectPaths(self, diff):
179 paths_by_status = [set(), set(), set(), set()]
180 def helper(group):
181 for s in group:
182 if s.IsGroup():
183 helper(s)
184 else:
185 status = group.DiffStatus(s)
186 paths_by_status[status].add(s.source_path or s.object_path)
187 helper(diff)
188 # Show only paths that have no changed symbols (pure adds / removes).
189 unchanged, changed, added, removed = paths_by_status
190 added.difference_update(unchanged)
191 added.difference_update(changed)
192 removed.difference_update(unchanged)
193 removed.difference_update(changed)
194 yield '{} paths added, {} removed, {} changed'.format(
195 len(added), len(removed), len(changed))
196
197 if self.verbose and len(added):
198 yield 'Added files:'
199 for p in sorted(added):
200 yield ' ' + p
201 if self.verbose and len(removed):
202 yield 'Removed files:'
203 for p in sorted(removed):
204 yield ' ' + p
205 if self.verbose and len(changed):
206 yield 'Changed files:'
207 for p in sorted(changed):
208 yield ' ' + p
209
185 def _DescribeSymbolDiff(self, diff): 210 def _DescribeSymbolDiff(self, diff):
186 header_template = ('{} symbols added (+), {} changed (~), {} removed (-), ' 211 header_template = ('{} symbols added (+), {} changed (~), {} removed (-), '
187 '{} unchanged ({})') 212 '{} unchanged ({})')
188 unchanged_msg = '=' if self.verbose else 'not shown' 213 unchanged_msg = '=' if self.verbose else 'not shown'
189 symbol_delta_desc = [header_template.format( 214 symbol_delta_desc = [header_template.format(
190 diff.added_count, diff.changed_count, diff.removed_count, 215 diff.added_count, diff.changed_count, diff.removed_count,
191 diff.unchanged_count, unchanged_msg)] 216 diff.unchanged_count, unchanged_msg)]
192 217 path_delta_desc = self._DescribeDiffObjectPaths(diff)
193 similar_paths = set()
194 added_paths = set()
195 removed_paths = set()
196 for s in diff:
197 if diff.IsAdded(s):
198 added_paths.add(s.object_path)
199 elif diff.IsRemoved(s):
200 removed_paths.add(s.object_path)
201 else:
202 similar_paths.add(s.object_path)
203 added_paths.difference_update(similar_paths)
204 removed_paths.difference_update(similar_paths)
205 path_delta_desc = ['{} object files added, {} removed'.format(
206 len(added_paths), len(removed_paths))]
207 if self.verbose and len(added_paths):
208 path_delta_desc.append('Added files:')
209 path_delta_desc.extend(' ' + p for p in sorted(added_paths))
210 if self.verbose and len(removed_paths):
211 path_delta_desc.append('Removed files:')
212 path_delta_desc.extend(' ' + p for p in sorted(removed_paths))
213 218
214 diff = diff if self.verbose else diff.WhereNotUnchanged() 219 diff = diff if self.verbose else diff.WhereNotUnchanged()
215 group_desc = self._DescribeSymbolGroup(diff) 220 group_desc = self._DescribeSymbolGroup(diff)
216 return itertools.chain(symbol_delta_desc, path_delta_desc, ('',), 221 return itertools.chain(symbol_delta_desc, path_delta_desc, ('',),
217 group_desc) 222 group_desc)
218 223
219 def _DescribeSizeInfoDiff(self, diff): 224 def _DescribeSizeInfoDiff(self, diff):
220 common_metadata = {k: v for k, v in diff.before_metadata.iteritems() 225 common_metadata = {k: v for k, v in diff.before_metadata.iteritems()
221 if diff.after_metadata[k] == v} 226 if diff.after_metadata[k] == v}
222 before_metadata = {k: v for k, v in diff.before_metadata.iteritems() 227 before_metadata = {k: v for k, v in diff.before_metadata.iteritems()
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 341
337 def GenerateLines(obj, verbose=False, recursive=False): 342 def GenerateLines(obj, verbose=False, recursive=False):
338 """Returns an iterable of lines (without \n) that describes |obj|.""" 343 """Returns an iterable of lines (without \n) that describes |obj|."""
339 return Describer(verbose=verbose, recursive=recursive).GenerateLines(obj) 344 return Describer(verbose=verbose, recursive=recursive).GenerateLines(obj)
340 345
341 346
342 def WriteLines(lines, func): 347 def WriteLines(lines, func):
343 for l in lines: 348 for l in lines:
344 func(l) 349 func(l)
345 func('\n') 350 func('\n')
OLDNEW
« no previous file with comments | « tools/binary_size/diagnose_bloat.py ('k') | tools/binary_size/libsupersize/integration_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698