| Index: tools/binary_size/diagnose_bloat.py
|
| diff --git a/tools/binary_size/diagnose_bloat.py b/tools/binary_size/diagnose_bloat.py
|
| index 17a49b3935d66e9192c07d65c8b0dd5cedc2ab50..a1cb5da655df0a9f9120a1232a9d9c4452e92063 100755
|
| --- a/tools/binary_size/diagnose_bloat.py
|
| +++ b/tools/binary_size/diagnose_bloat.py
|
| @@ -29,7 +29,6 @@ import zipfile
|
|
|
| _COMMIT_COUNT_WARN_THRESHOLD = 15
|
| _ALLOWED_CONSECUTIVE_FAILURES = 2
|
| -_DIFF_DETAILS_LINES_THRESHOLD = 100
|
| _SRC_ROOT = os.path.abspath(
|
| os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
|
| _DEFAULT_ARCHIVE_DIR = os.path.join(_SRC_ROOT, 'out', 'binary-size-results')
|
| @@ -50,10 +49,11 @@ class BaseDiff(object):
|
| def AppendResults(self, logfile):
|
| """Print and write diff results to an open |logfile|."""
|
| _PrintAndWriteToFile(logfile, self.banner)
|
| - _PrintAndWriteToFile(logfile, 'Summary:')
|
| - _PrintAndWriteToFile(logfile, self.Summary())
|
| - _PrintAndWriteToFile(logfile, '\nDetails:')
|
| - _PrintAndWriteToFile(logfile, self.DetailedResults())
|
| + for s in self.Summary():
|
| + print s
|
| + print
|
| + for s in self.DetailedResults():
|
| + logfile.write(s + '\n')
|
|
|
| @property
|
| def summary_stat(self):
|
| @@ -78,7 +78,6 @@ class BaseDiff(object):
|
|
|
|
|
| class NativeDiff(BaseDiff):
|
| - _RE_SUMMARY = re.compile(r'Section Sizes .*?\n\n.*?(?=\n\n)', flags=re.DOTALL)
|
| _RE_SUMMARY_STAT = re.compile(
|
| r'Section Sizes \(Total=(?P<value>\d+) (?P<units>\w+)\)')
|
| _SUMMARY_STAT_NAME = 'Native Library Delta'
|
| @@ -101,7 +100,7 @@ class NativeDiff(BaseDiff):
|
| return self._diff.splitlines()
|
|
|
| def Summary(self):
|
| - return NativeDiff._RE_SUMMARY.search(self._diff).group()
|
| + return self.DetailedResults()[:100]
|
|
|
| def ProduceDiff(self, before_dir, after_dir):
|
| before_size = os.path.join(before_dir, self._size_name)
|
| @@ -113,6 +112,10 @@ class NativeDiff(BaseDiff):
|
| class ResourceSizesDiff(BaseDiff):
|
| _RESOURCE_SIZES_PATH = os.path.join(
|
| _SRC_ROOT, 'build', 'android', 'resource_sizes.py')
|
| + _SUMMARY_SECTIONS = ('Breakdown', 'Specifics')
|
| + # Sections where it makes sense to sum subsections into a section total.
|
| + _AGGREGATE_SECTIONS = (
|
| + 'InstallBreakdown', 'Breakdown', 'MainLibInfo', 'Uncompressed')
|
|
|
| def __init__(self, apk_name, slow_options=False):
|
| self._apk_name = apk_name
|
| @@ -122,23 +125,24 @@ class ResourceSizesDiff(BaseDiff):
|
|
|
| @property
|
| def summary_stat(self):
|
| - for s in self._diff:
|
| - if 'normalized' in s.name:
|
| - return s
|
| + for section_name, results in self._diff.iteritems():
|
| + for subsection_name, value, units in results:
|
| + if 'normalized' in subsection_name:
|
| + full_name = '{} {}'.format(section_name, subsection_name)
|
| + return _DiffResult(full_name, value, units)
|
| return None
|
|
|
| def DetailedResults(self):
|
| - return ['{:>+10,} {} {}'.format(value, units, name)
|
| - for name, value, units in self._diff]
|
| + return self._ResultLines()
|
|
|
| def Summary(self):
|
| - return 'Normalized APK size: {:+,} {}'.format(
|
| - self.summary_stat.value, self.summary_stat.units)
|
| + return self._ResultLines(
|
| + include_sections=ResourceSizesDiff._SUMMARY_SECTIONS)
|
|
|
| def ProduceDiff(self, before_dir, after_dir):
|
| before = self._RunResourceSizes(before_dir)
|
| after = self._RunResourceSizes(after_dir)
|
| - diff = []
|
| + self._diff = collections.defaultdict(list)
|
| for section, section_dict in after.iteritems():
|
| for subsection, v in section_dict.iteritems():
|
| # Ignore entries when resource_sizes.py chartjson format has changed.
|
| @@ -149,12 +153,36 @@ class ResourceSizesDiff(BaseDiff):
|
| 'Found differing dict structures for resource_sizes.py, '
|
| 'skipping %s %s', section, subsection)
|
| else:
|
| - diff.append(
|
| - _DiffResult(
|
| - '%s %s' % (section, subsection),
|
| - v['value'] - before[section][subsection]['value'],
|
| - v['units']))
|
| - self._diff = sorted(diff, key=lambda x: abs(x.value), reverse=True)
|
| + self._diff[section].append(_DiffResult(
|
| + subsection,
|
| + v['value'] - before[section][subsection]['value'],
|
| + v['units']))
|
| +
|
| + def _ResultLines(self, include_sections=None):
|
| + """Generates diff lines for the specified sections (defaults to all)."""
|
| + ret = []
|
| + for section_name, section_results in self._diff.iteritems():
|
| + section_no_target = re.sub(r'^.*_', '', section_name)
|
| + if not include_sections or section_no_target in include_sections:
|
| + subsection_lines = []
|
| + section_sum = 0
|
| + units = ''
|
| + for name, value, units in section_results:
|
| + # Omit subsections with no changes for summaries.
|
| + if value == 0 and include_sections:
|
| + continue
|
| + section_sum += value
|
| + subsection_lines.append('{:>+10,} {} {}'.format(value, units, name))
|
| + section_header = section_name
|
| + if section_no_target in ResourceSizesDiff._AGGREGATE_SECTIONS:
|
| + section_header += ' ({:+,} {})'.format(section_sum, units)
|
| + # Omit sections with empty subsections.
|
| + if subsection_lines:
|
| + ret.append(section_header)
|
| + ret.extend(subsection_lines)
|
| + if not ret:
|
| + ret = ['Empty ' + self.name]
|
| + return ret
|
|
|
| def _RunResourceSizes(self, archive_dir):
|
| apk_path = os.path.join(archive_dir, self._apk_name)
|
| @@ -656,17 +684,12 @@ def _ExtractFiles(to_extract, dst, z):
|
|
|
|
|
| def _PrintAndWriteToFile(logfile, s, *args, **kwargs):
|
| - """Write and print |s| thottling output if |s| is a large list."""
|
| if isinstance(s, basestring):
|
| - s = s.format(*args, **kwargs)
|
| - print s
|
| - logfile.write('%s\n' % s)
|
| + data = s.format(*args, **kwargs) + '\n'
|
| else:
|
| - for l in s[:_DIFF_DETAILS_LINES_THRESHOLD]:
|
| - print l
|
| - if len(s) > _DIFF_DETAILS_LINES_THRESHOLD:
|
| - print '\nOutput truncated, see %s for more.' % logfile.name
|
| - logfile.write('\n'.join(s))
|
| + data = '\n'.join(s) + '\n'
|
| + sys.stdout.write(data)
|
| + logfile.write(data)
|
|
|
|
|
| @contextmanager
|
|
|