| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright 2013 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """Profiler to compare various compression levels with regards to speed | |
| 7 and final size when compressing the full set of files from a given | |
| 8 isolated file. | |
| 9 """ | |
| 10 | |
| 11 import bz2 | |
| 12 import optparse | |
| 13 import os | |
| 14 import shutil | |
| 15 import subprocess | |
| 16 import sys | |
| 17 import tempfile | |
| 18 import time | |
| 19 import zlib | |
| 20 | |
| 21 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| 22 sys.path.insert(0, ROOT_DIR) | |
| 23 | |
| 24 from utils import tools | |
| 25 | |
| 26 | |
| 27 def zip_file(compressor_constructor, compression_level, filename): | |
| 28 compressed_size = 0 | |
| 29 compressor = compressor_constructor(compression_level) | |
| 30 with open(filename, 'rb') as f: | |
| 31 while True: | |
| 32 chunk = f.read(16 * 1024) | |
| 33 if not chunk: | |
| 34 break | |
| 35 compressed_size += len(compressor.compress(f.read())) | |
| 36 compressed_size += len(compressor.flush()) | |
| 37 | |
| 38 return compressed_size | |
| 39 | |
| 40 | |
| 41 def zip_directory(compressor_constructor, compression_level, root_dir): | |
| 42 compressed_size = 0 | |
| 43 for root, _, files in os.walk(root_dir): | |
| 44 compressed_size += sum(zip_file(compressor_constructor, compression_level, | |
| 45 os.path.join(root, name)) | |
| 46 for name in files) | |
| 47 return compressed_size | |
| 48 | |
| 49 | |
| 50 def profile_compress(zip_module_name, compressor_constructor, | |
| 51 compression_range, compress_func, compress_target): | |
| 52 for i in compression_range: | |
| 53 start_time = time.time() | |
| 54 compressed_size = compress_func(compressor_constructor, i, compress_target) | |
| 55 end_time = time.time() | |
| 56 | |
| 57 print('%4s at compression level %s, total size %11d, time taken %6.3f' % | |
| 58 (zip_module_name, i, compressed_size, end_time - start_time)) | |
| 59 | |
| 60 | |
| 61 def tree_files(root_dir): | |
| 62 file_set = {} | |
| 63 for root, _, files in os.walk(root_dir): | |
| 64 for name in files: | |
| 65 filename = os.path.join(root, name) | |
| 66 file_set[filename] = os.stat(filename).st_size | |
| 67 | |
| 68 return file_set | |
| 69 | |
| 70 | |
| 71 def main(): | |
| 72 tools.disable_buffering() | |
| 73 parser = optparse.OptionParser() | |
| 74 parser.add_option('-s', '--isolated', help='.isolated file to profile with.') | |
| 75 parser.add_option('--largest_files', type='int', | |
| 76 help='If this is set, instead of compressing all the ' | |
| 77 'files, only the large n files will be compressed') | |
| 78 options, args = parser.parse_args() | |
| 79 | |
| 80 if args: | |
| 81 parser.error('Unknown args passed in; %s' % args) | |
| 82 if not options.isolated: | |
| 83 parser.error('The .isolated file must be given.') | |
| 84 | |
| 85 temp_dir = None | |
| 86 try: | |
| 87 temp_dir = tempfile.mkdtemp() | |
| 88 | |
| 89 # Create a directory of the required files | |
| 90 subprocess.check_call([os.path.join(ROOT_DIR, 'isolate.py'), | |
| 91 'remap', | |
| 92 '-s', options.isolated, | |
| 93 '--outdir', temp_dir]) | |
| 94 | |
| 95 file_set = tree_files(temp_dir) | |
| 96 | |
| 97 if options.largest_files: | |
| 98 sorted_by_size = sorted(file_set.iteritems(), key=lambda x: x[1], | |
| 99 reverse=True) | |
| 100 files_to_compress = sorted_by_size[:options.largest_files] | |
| 101 | |
| 102 for filename, size in files_to_compress: | |
| 103 print('Compressing %s, uncompressed size %d' % (filename, size)) | |
| 104 | |
| 105 profile_compress('zlib', zlib.compressobj, range(10), zip_file, | |
| 106 filename) | |
| 107 profile_compress('bz2', bz2.BZ2Compressor, range(1, 10), zip_file, | |
| 108 filename) | |
| 109 else: | |
| 110 print('Number of files: %s' % len(file_set)) | |
| 111 print('Total size: %s' % sum(file_set.itervalues())) | |
| 112 | |
| 113 # Profile! | |
| 114 profile_compress('zlib', zlib.compressobj, range(10), zip_directory, | |
| 115 temp_dir) | |
| 116 profile_compress('bz2', bz2.BZ2Compressor, range(1, 10), zip_directory, | |
| 117 temp_dir) | |
| 118 finally: | |
| 119 shutil.rmtree(temp_dir) | |
| 120 | |
| 121 | |
| 122 if __name__ == '__main__': | |
| 123 sys.exit(main()) | |
| OLD | NEW |