|  | @@ -0,0 +1,102 @@
 | 
	
		
			
				|  |  | +#!/usr/bin/env python2.7
 | 
	
		
			
				|  |  | +#
 | 
	
		
			
				|  |  | +# Copyright 2018 gRPC authors.
 | 
	
		
			
				|  |  | +#
 | 
	
		
			
				|  |  | +# Licensed under the Apache License, Version 2.0 (the "License");
 | 
	
		
			
				|  |  | +# you may not use this file except in compliance with the License.
 | 
	
		
			
				|  |  | +# You may obtain a copy of the License at
 | 
	
		
			
				|  |  | +#
 | 
	
		
			
				|  |  | +#     http://www.apache.org/licenses/LICENSE-2.0
 | 
	
		
			
				|  |  | +#
 | 
	
		
			
				|  |  | +# Unless required by applicable law or agreed to in writing, software
 | 
	
		
			
				|  |  | +# distributed under the License is distributed on an "AS IS" BASIS,
 | 
	
		
			
				|  |  | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
	
		
			
				|  |  | +# See the License for the specific language governing permissions and
 | 
	
		
			
				|  |  | +# limitations under the License.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import argparse
 | 
	
		
			
				|  |  | +import glob
 | 
	
		
			
				|  |  | +import multiprocessing
 | 
	
		
			
				|  |  | +import os
 | 
	
		
			
				|  |  | +import shutil
 | 
	
		
			
				|  |  | +import subprocess
 | 
	
		
			
				|  |  | +import sys
 | 
	
		
			
				|  |  | +from parse_link_map import parse_link_map
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +sys.path.append(
 | 
	
		
			
				|  |  | +    os.path.join(
 | 
	
		
			
				|  |  | +        os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils'))
 | 
	
		
			
				|  |  | +import comment_on_pr
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +size_labels = ('Core', 'ObjC', 'BoringSSL', 'Protobuf', 'Total')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +argp = argparse.ArgumentParser(description='Perform diff on microbenchmarks')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +argp.add_argument(
 | 
	
		
			
				|  |  | +    '-d',
 | 
	
		
			
				|  |  | +    '--diff_base',
 | 
	
		
			
				|  |  | +    type=str,
 | 
	
		
			
				|  |  | +    help='Commit or branch to compare the current one to')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +args = argp.parse_args()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +def dir_size(dir):
 | 
	
		
			
				|  |  | +    total = 0
 | 
	
		
			
				|  |  | +    for dirpath, dirnames, filenames in os.walk(dir):
 | 
	
		
			
				|  |  | +        for f in filenames:
 | 
	
		
			
				|  |  | +            fp = os.path.join(dirpath, f)
 | 
	
		
			
				|  |  | +            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:
 | 
	
		
			
				|  |  | +        link_map_filename = 'Build/Intermediates.noindex/Sample.build/Release-iphoneos/Sample.build/Sample-LinkMap-normal-arm64.txt'
 | 
	
		
			
				|  |  | +        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')
 | 
	
		
			
				|  |  | +        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')
 | 
	
		
			
				|  |  | +        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)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +text = ''
 | 
	
		
			
				|  |  | +for frameworks in [False, True]:
 | 
	
		
			
				|  |  | +    build('new', frameworks)
 | 
	
		
			
				|  |  | +    new_size = get_size('new', frameworks)
 | 
	
		
			
				|  |  | +    old_size = None
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if args.diff_base:
 | 
	
		
			
				|  |  | +        old = 'old'
 | 
	
		
			
				|  |  | +        where_am_i = subprocess.check_output(
 | 
	
		
			
				|  |  | +            ['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
 | 
	
		
			
				|  |  | +        subprocess.check_call(['git', 'checkout', '--', '.'])
 | 
	
		
			
				|  |  | +        subprocess.check_call(['git', 'checkout', args.diff_base])
 | 
	
		
			
				|  |  | +        subprocess.check_call(['git', 'submodule', 'update'])
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            build('old', frameworks)
 | 
	
		
			
				|  |  | +            old_size = get_size('old', frameworks)
 | 
	
		
			
				|  |  | +        finally:
 | 
	
		
			
				|  |  | +            subprocess.check_call(['git', 'checkout', '--', '.'])
 | 
	
		
			
				|  |  | +            subprocess.check_call(['git', 'checkout', where_am_i])
 | 
	
		
			
				|  |  | +            subprocess.check_call(['git', 'submodule', 'update'])
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    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 '')
 | 
	
		
			
				|  |  | +    text += '\n'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +print text
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +comment_on_pr.comment_on_pr('```\n%s\n```' % text)
 |