From eb22c792f27a19b4430e32ed3f050020fe8e6242 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 6 Jun 2018 15:40:46 -0700 Subject: Provide diff sign for each line --- tools/profiling/ios_bin/binary_diff.py | 43 +++++++-- tools/profiling/ios_bin/parse_link_map.py | 148 +++++++++++++++--------------- 2 files changed, 110 insertions(+), 81 deletions(-) (limited to 'tools/profiling') diff --git a/tools/profiling/ios_bin/binary_diff.py b/tools/profiling/ios_bin/binary_diff.py index 0ea75ef750..6d5ae65e46 100755 --- a/tools/profiling/ios_bin/binary_diff.py +++ b/tools/profiling/ios_bin/binary_diff.py @@ -30,7 +30,8 @@ import comment_on_pr size_labels = ('Core', 'ObjC', 'BoringSSL', 'Protobuf', 'Total') -argp = argparse.ArgumentParser(description='Binary size diff of gRPC Objective-C sample') +argp = argparse.ArgumentParser( + description='Binary size diff of gRPC Objective-C sample') argp.add_argument( '-d', @@ -40,6 +41,7 @@ argp.add_argument( args = argp.parse_args() + def dir_size(dir): total = 0 for dirpath, dirnames, filenames in os.walk(dir): @@ -48,6 +50,7 @@ def dir_size(dir): total += os.stat(fp).st_size return total + def get_size(where, frameworks): build_dir = 'src/objective-c/examples/Sample/Build-%s/' % where if not frameworks: @@ -55,19 +58,30 @@ def get_size(where, frameworks): return parse_link_map(build_dir + link_map_filename) else: framework_dir = 'Build/Products/Release-iphoneos/Sample.app/Frameworks/' - boringssl_size = dir_size(build_dir + framework_dir + 'openssl.framework') + boringssl_size = dir_size( + build_dir + framework_dir + 'openssl.framework') core_size = dir_size(build_dir + framework_dir + 'grpc.framework') objc_size = dir_size(build_dir + framework_dir + 'GRPCClient.framework') + \ dir_size(build_dir + framework_dir + 'RxLibrary.framework') + \ dir_size(build_dir + framework_dir + 'ProtoRPC.framework') - protobuf_size = dir_size(build_dir + framework_dir + 'Protobuf.framework') - app_size = dir_size(build_dir + 'Build/Products/Release-iphoneos/Sample.app') + protobuf_size = dir_size( + build_dir + framework_dir + 'Protobuf.framework') + app_size = dir_size( + build_dir + 'Build/Products/Release-iphoneos/Sample.app') return core_size, objc_size, boringssl_size, protobuf_size, app_size + def build(where, frameworks): - shutil.rmtree('src/objective-c/examples/Sample/Build-%s' % where, ignore_errors=True) - subprocess.check_call('CONFIG=opt EXAMPLE_PATH=src/objective-c/examples/Sample SCHEME=Sample FRAMEWORKS=%s ./build_one_example.sh' % ('YES' if frameworks else 'NO'), shell=True, cwd='src/objective-c/tests') - os.rename('src/objective-c/examples/Sample/Build', 'src/objective-c/examples/Sample/Build-%s' % where) + shutil.rmtree( + 'src/objective-c/examples/Sample/Build-%s' % where, ignore_errors=True) + subprocess.check_call( + 'CONFIG=opt EXAMPLE_PATH=src/objective-c/examples/Sample SCHEME=Sample FRAMEWORKS=%s ./build_one_example.sh' + % ('YES' if frameworks else 'NO'), + shell=True, + cwd='src/objective-c/tests') + os.rename('src/objective-c/examples/Sample/Build', + 'src/objective-c/examples/Sample/Build-%s' % where) + text = '' for frameworks in [False, True]: @@ -90,11 +104,22 @@ for frameworks in [False, True]: subprocess.check_call(['git', 'checkout', where_am_i]) subprocess.check_call(['git', 'submodule', 'update']) - text += ('****************FRAMEWORKS*****************\n' if frameworks else '******************STATIC*******************\n') + text += ('****************FRAMEWORKS*****************\n' + if frameworks else '******************STATIC*******************\n') row_format = "{:>10}{:>15}{:>15}" + '\n' text += row_format.format('New size', '', 'Old size') for i in range(0, len(size_labels)): - text += ('\n' if i == len(size_labels) - 1 else '') + row_format.format('{:,}'.format(new_size[i]), size_labels[i], '{:,}'.format(old_size[i]) if old_size != None else '') + if old_size == None: + diff_sign = ' ' + elif new_size[i] == old_size[i]: + diff_sign = ' (=)' + elif new_size[i] > old_size[i]: + diff_sign = ' (>)' + else: + diff_sign = ' (<)' + text += ('\n' if i == len(size_labels) - 1 else '') + row_format.format( + '{:,}'.format(new_size[i]), size_labels[i] + diff_sign, + '{:,}'.format(old_size[i]) if old_size != None else '') text += '\n' print text diff --git a/tools/profiling/ios_bin/parse_link_map.py b/tools/profiling/ios_bin/parse_link_map.py index 3ce166a6be..eaa1d6e060 100755 --- a/tools/profiling/ios_bin/parse_link_map.py +++ b/tools/profiling/ios_bin/parse_link_map.py @@ -21,80 +21,84 @@ import sys import re + def parse_link_map(filename): - table_tag = {} - state = "start" - - table_stats_symbol = {} - table_stats_dead = {} - section_total_size = 0 - symbol_total_size = 0 - - boringssl_size = 0 - core_size = 0 - objc_size = 0 - protobuf_size = 0 - - lines = list(open(filename)) - for line in lines: - line_stripped = line[:-1] - if "# Object files:" == line_stripped: - state = "object" - continue - elif "# Sections:" == line_stripped: - state = "section" - continue - elif "# Symbols:" == line_stripped: - state = "symbol" - continue - elif "# Dead Stripped Symbols:" == line_stripped: - state = "dead" - continue - - if state == "object": - segs = re.search('(\[ *[0-9]*\]) (.*)', line_stripped) - table_tag[segs.group(1)] = segs.group(2) - - if state == "section": - if len(line_stripped) == 0 or line_stripped[0] == '#': - continue - segs = re.search('^(.+?)\s+(.+?)\s+.*', line_stripped) - section_total_size += int(segs.group(2), 16) - - if state == "symbol": - if len(line_stripped) == 0 or line_stripped[0] == '#': - continue - segs = re.search('^.+?\s+(.+?)\s+(\[.+?\]).*', line_stripped) - target = table_tag[segs.group(2)] - target_stripped = re.search('^(.*?)(\(.+?\))?$', target).group(1) - size = int(segs.group(1), 16) - if not target_stripped in table_stats_symbol: - table_stats_symbol[target_stripped] = 0 - table_stats_symbol[target_stripped] += size - if 'BoringSSL' in target_stripped: - boringssl_size += size - elif 'libgRPC-Core' in target_stripped: - core_size += size - elif 'libgRPC-RxLibrary' in target_stripped or \ - 'libgRPC' in target_stripped or \ - 'libgRPC-ProtoLibrary' in target_stripped: - objc_size += size - elif 'libProtobuf' in target_stripped: - protobuf_size += size - - for target in table_stats_symbol: - symbol_total_size += table_stats_symbol[target] - - return core_size, objc_size, boringssl_size, protobuf_size, symbol_total_size + table_tag = {} + state = "start" + + table_stats_symbol = {} + table_stats_dead = {} + section_total_size = 0 + symbol_total_size = 0 + + boringssl_size = 0 + core_size = 0 + objc_size = 0 + protobuf_size = 0 + + lines = list(open(filename)) + for line in lines: + line_stripped = line[:-1] + if "# Object files:" == line_stripped: + state = "object" + continue + elif "# Sections:" == line_stripped: + state = "section" + continue + elif "# Symbols:" == line_stripped: + state = "symbol" + continue + elif "# Dead Stripped Symbols:" == line_stripped: + state = "dead" + continue + + if state == "object": + segs = re.search('(\[ *[0-9]*\]) (.*)', line_stripped) + table_tag[segs.group(1)] = segs.group(2) + + if state == "section": + if len(line_stripped) == 0 or line_stripped[0] == '#': + continue + segs = re.search('^(.+?)\s+(.+?)\s+.*', line_stripped) + section_total_size += int(segs.group(2), 16) + + if state == "symbol": + if len(line_stripped) == 0 or line_stripped[0] == '#': + continue + segs = re.search('^.+?\s+(.+?)\s+(\[.+?\]).*', line_stripped) + target = table_tag[segs.group(2)] + target_stripped = re.search('^(.*?)(\(.+?\))?$', target).group(1) + size = int(segs.group(1), 16) + if not target_stripped in table_stats_symbol: + table_stats_symbol[target_stripped] = 0 + table_stats_symbol[target_stripped] += size + if 'BoringSSL' in target_stripped: + boringssl_size += size + elif 'libgRPC-Core' in target_stripped: + core_size += size + elif 'libgRPC-RxLibrary' in target_stripped or \ + 'libgRPC' in target_stripped or \ + 'libgRPC-ProtoLibrary' in target_stripped: + objc_size += size + elif 'libProtobuf' in target_stripped: + protobuf_size += size + + for target in table_stats_symbol: + symbol_total_size += table_stats_symbol[target] + + return core_size, objc_size, boringssl_size, protobuf_size, symbol_total_size + def main(): - filename = sys.argv[1] - core_size, objc_size, boringssl_size, protobuf_size, total_size = parse_link_map(filename) - print('Core size:{:,}'.format(core_size)) - print('ObjC size:{:,}'.format(objc_size)) - print('BoringSSL size:{:,}'.format(boringssl_size)) - print('Protobuf size:{:,}\n'.format(protobuf_size)) - print('Total size:{:,}'.format(total_size)) + filename = sys.argv[1] + core_size, objc_size, boringssl_size, protobuf_size, total_size = parse_link_map( + filename) + print('Core size:{:,}'.format(core_size)) + print('ObjC size:{:,}'.format(objc_size)) + print('BoringSSL size:{:,}'.format(boringssl_size)) + print('Protobuf size:{:,}\n'.format(protobuf_size)) + print('Total size:{:,}'.format(total_size)) + if __name__ == "__main__": - main() + main() -- cgit v1.2.3