| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 4 # for details. All rights reserved. Use of this source code is governed by a | 4 # for details. All rights reserved. Use of this source code is governed by a |
| 5 # BSD-style license that can be found in the LICENSE file. | 5 # BSD-style license that can be found in the LICENSE file. |
| 6 | 6 |
| 7 import datetime | 7 import datetime |
| 8 import math | 8 import math |
| 9 try: | 9 try: |
| 10 from matplotlib.font_manager import FontProperties | 10 from matplotlib.font_manager import FontProperties |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 Args: | 78 Args: |
| 79 failed_once True if we have attempted to build this once before, and we've | 79 failed_once True if we have attempted to build this once before, and we've |
| 80 failed, indicating the build is broken. | 80 failed, indicating the build is broken. |
| 81 Returns: | 81 Returns: |
| 82 err_code = 1 if there was a problem building two times in a row.""" | 82 err_code = 1 if there was a problem building two times in a row.""" |
| 83 os.chdir(DART_INSTALL_LOCATION) | 83 os.chdir(DART_INSTALL_LOCATION) |
| 84 #Revert our newly built minfrog to prevent conflicts when we update | 84 #Revert our newly built minfrog to prevent conflicts when we update |
| 85 RunCmd(['svn', 'revert', os.path.join(os.getcwd(), 'frog', 'minfrog')]) | 85 RunCmd(['svn', 'revert', os.path.join(os.getcwd(), 'frog', 'minfrog')]) |
| 86 | 86 |
| 87 RunCmd(['gclient', 'sync']) | 87 RunCmd(['gclient', 'sync']) |
| 88 lines = RunCmd([os.path.join('.', 'tools', 'build.py'), '-m', 'release']) | 88 #TODO(efortuna): Temporary fix to get IE data without requiring Dart to build |
| 89 os.chdir('frog') | 89 # on Windows. Take this out once we have SDKs or can build on Windows. |
| 90 lines += RunCmd([os.path.join('..', 'tools', 'build.py'), '-m', | 90 if platform.system() != 'Windows': |
| 91 'debug,release']) | 91 lines = RunCmd([os.path.join('.', 'tools', 'build.py'), '-m', 'release']) |
| 92 os.chdir('..') | 92 os.chdir('frog') |
| 93 lines += RunCmd([os.path.join('..', 'tools', 'build.py'), '-m', |
| 94 'debug,release']) |
| 95 os.chdir('..') |
| 93 | 96 |
| 94 for line in lines: | 97 for line in lines: |
| 95 if 'BUILD FAILED' in lines: | 98 if 'BUILD FAILED' in lines: |
| 96 if failed_once: | 99 if failed_once: |
| 97 # Someone checked in a broken build! Just stop trying to make it work | 100 # Someone checked in a broken build! Just stop trying to make it work |
| 98 # and wait for the next hour to try again. | 101 # and wait for the next hour to try again. |
| 99 print 'Broken Build' | 102 print 'Broken Build' |
| 100 return 1 | 103 return 1 |
| 101 #Remove the xcode directory and attempt to build again. If it still | 104 #Remove the xcode directory and attempt to build again. If it still |
| 102 #fails, abort, and try again next hour. | 105 #fails, abort, and try again next hour. |
| 103 out_dir = 'out' | 106 out_dir = 'out' |
| 104 if platform.system() == 'Darwin': | 107 if platform.system() == 'Darwin': |
| 105 out_dir = 'xcodebuild' | 108 out_dir = 'xcodebuild' |
| 106 shutil.rmtree(os.path.join(os.getcwd(), out_dir, 'Release_ia32')) | 109 shutil.rmtree(os.path.join(os.getcwd(), out_dir, 'Release_ia32')) |
| 107 shutil.rmtree(os.path.join(os.getcwd(), 'frog', out_dir, | 110 shutil.rmtree(os.path.join(os.getcwd(), 'frog', out_dir, |
| 108 'Debug_ia32')) | 111 'Debug_ia32')) |
| 109 shutil.rmtree(os.path.join(os.getcwd(), 'frog', out_dir, | 112 shutil.rmtree(os.path.join(os.getcwd(), 'frog', out_dir, |
| 110 'Release_ia32')) | 113 'Release_ia32')) |
| 111 SyncAndBuild(True) | 114 SyncAndBuild(True) |
| 112 return 0 | 115 return 0 |
| 113 | 116 |
| 114 def EnsureOutputDirectory(dir_name): | 117 def EnsureOutputDirectory(dir_name): |
| 115 """Test that the listed directory name exists, and if not, create one for | 118 """Test that the listed directory name exists, and if not, create one for |
| 116 our output to be placed. | 119 our output to be placed. |
| 117 Args: | 120 Args: |
| 118 dir_name the directory we will create if it does not exist.""" | 121 dir_name the directory we will create if it does not exist.""" |
| 119 dir_path = os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing', | 122 dir_path = os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing', |
| 120 'perf_testing', dir_name) | 123 'perf_testing', dir_name) |
| 121 if not os.path.exists(dir_path): | 124 if not os.path.exists(dir_path): |
| 122 os.mkdir(dir_path) | 125 os.mkdir(dir_path) |
| 123 print 'Creating output directory ', dir_path | 126 print 'Creating output directory ', dir_path |
| 124 | 127 |
| 125 def HasNewCode(): | 128 def HasNewCode(): |
| 126 """Tests if there are any newer versions of files on the server.""" | 129 """Tests if there are any newer versions of files on the server.""" |
| 127 os.chdir(DART_INSTALL_LOCATION) | 130 os.chdir(DART_INSTALL_LOCATION) |
| 128 results = RunCmd(['svn', 'st', '-u']) | 131 results = RunCmd(['svn', 'st', '-u']) |
| 129 for line in results: | 132 for line in results: |
| 130 if '*' in line: | 133 if '*' in line: |
| 131 return True | 134 return True |
| 132 return False | 135 return False |
| 133 | 136 |
| 134 def GetBrowsers(): | 137 def GetBrowsers(): |
| 135 if not PERFBOT_MODE: | 138 if not PERFBOT_MODE: |
| 136 # Only Firefox (and Chrome, but we have Dump Render Tree) works in Linux | 139 # Only Firefox (and Chrome, but we have Dump Render Tree) works in Linux |
| 137 return ['ff'] | 140 return ['ff'] |
| 138 browsers = ['ff', 'chrome'] | 141 browsers = ['ff', 'chrome', 'safari'] |
| 139 if platform.system() == 'Windows': | 142 if platform.system() == 'Windows': |
| 140 browsers += ['ie'] | 143 browsers += ['ie'] |
| 141 return browsers | 144 return browsers |
| 142 | 145 |
| 143 def GetVersions(): | 146 def GetVersions(): |
| 144 if not PERFBOT_MODE: | 147 if not PERFBOT_MODE: |
| 145 return [FROG] | 148 return [FROG] |
| 146 else: | 149 else: |
| 147 return V8_AND_FROG | 150 return V8_AND_FROG |
| 148 | 151 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 173 performance results will be stored. | 176 performance results will be stored. |
| 174 platform_list a list containing the platform(s) that our data has been | 177 platform_list a list containing the platform(s) that our data has been |
| 175 run on. (command line, firefox, chrome, etc) | 178 run on. (command line, firefox, chrome, etc) |
| 176 v8_and_or_frog_list a list specifying whether we hold data about Frog | 179 v8_and_or_frog_list a list specifying whether we hold data about Frog |
| 177 generated code, plain JS code (v8), or a combination of both. | 180 generated code, plain JS code (v8), or a combination of both. |
| 178 values_list a list containing the type of data we will be graphing | 181 values_list a list containing the type of data we will be graphing |
| 179 (benchmarks, percentage passing, etc)""" | 182 (benchmarks, percentage passing, etc)""" |
| 180 self.result_folder_name = result_folder_name | 183 self.result_folder_name = result_folder_name |
| 181 # cur_time is used as a timestamp of when this performance test was run. | 184 # cur_time is used as a timestamp of when this performance test was run. |
| 182 self.cur_time = str(time.mktime(datetime.datetime.now().timetuple())) | 185 self.cur_time = str(time.mktime(datetime.datetime.now().timetuple())) |
| 183 self.browser_color = {'chrome': 'green', 'ie': 'blue', 'ff': 'red'} | 186 self.browser_color = {'chrome': 'green', 'ie': 'blue', 'ff': 'red', |
| 187 'safari':'black'} |
| 184 self.values_list = values_list | 188 self.values_list = values_list |
| 185 self.platform_list = platform_list | 189 self.platform_list = platform_list |
| 186 self.revision_dict = dict() | 190 self.revision_dict = dict() |
| 187 self.values_dict = dict() | 191 self.values_dict = dict() |
| 188 self.color_index = 0 | 192 self.color_index = 0 |
| 189 for platform in platform_list: | 193 for platform in platform_list: |
| 190 self.revision_dict[platform] = dict() | 194 self.revision_dict[platform] = dict() |
| 191 self.values_dict[platform] = dict() | 195 self.values_dict[platform] = dict() |
| 192 for f in v8_and_or_frog_list: | 196 for f in v8_and_or_frog_list: |
| 193 self.revision_dict[platform][f] = dict() | 197 self.revision_dict[platform][f] = dict() |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 geo_mean += math.log(self.values_dict[platform][frog_or_v8][benchmark][ | 300 geo_mean += math.log(self.values_dict[platform][frog_or_v8][benchmark][ |
| 297 len(self.values_dict[platform][frog_or_v8][benchmark]) - 1]) | 301 len(self.values_dict[platform][frog_or_v8][benchmark]) - 1]) |
| 298 | 302 |
| 299 mean = V8_MEAN | 303 mean = V8_MEAN |
| 300 if frog_or_v8 == FROG: | 304 if frog_or_v8 == FROG: |
| 301 mean = FROG_MEAN | 305 mean = FROG_MEAN |
| 302 self.values_dict[platform][frog_or_v8][mean] += \ | 306 self.values_dict[platform][frog_or_v8][mean] += \ |
| 303 [math.pow(math.e, geo_mean / len(BENCHMARKS))] | 307 [math.pow(math.e, geo_mean / len(BENCHMARKS))] |
| 304 self.revision_dict[platform][frog_or_v8][mean] += [svn_revision] | 308 self.revision_dict[platform][frog_or_v8][mean] += [svn_revision] |
| 305 | 309 |
| 306 def Cleanup(self): | |
| 307 pass | |
| 308 | |
| 309 def Run(self): | 310 def Run(self): |
| 310 """Run the benchmarks/tests from the command line and plot the | 311 """Run the benchmarks/tests from the command line and plot the |
| 311 results.""" | 312 results.""" |
| 312 if PERFBOT_MODE: | 313 if PERFBOT_MODE: |
| 313 plt.cla() # cla = clear current axes | 314 plt.cla() # cla = clear current axes |
| 314 os.chdir(DART_INSTALL_LOCATION) | 315 os.chdir(DART_INSTALL_LOCATION) |
| 315 EnsureOutputDirectory(self.result_folder_name) | 316 EnsureOutputDirectory(self.result_folder_name) |
| 316 EnsureOutputDirectory(GRAPH_OUT_DIR) | 317 EnsureOutputDirectory(GRAPH_OUT_DIR) |
| 317 self.RunTests() | 318 self.RunTests() |
| 318 os.chdir(os.path.join('tools', 'testing', 'perf_testing')) | 319 os.chdir(os.path.join('tools', 'testing', 'perf_testing')) |
| 319 | 320 |
| 320 # TODO(efortuna): You will want to make this only use a subset of the files | 321 # TODO(efortuna): You will want to make this only use a subset of the files |
| 321 # eventually. | 322 # eventually. |
| 322 files = os.listdir(self.result_folder_name) | 323 files = os.listdir(self.result_folder_name) |
| 323 | 324 |
| 324 for afile in files: | 325 for afile in files: |
| 325 if not afile.startswith('.'): | 326 if not afile.startswith('.'): |
| 326 self.ProcessFile(afile) | 327 self.ProcessFile(afile) |
| 327 | 328 |
| 328 if PERFBOT_MODE: | 329 if PERFBOT_MODE: |
| 329 self.PlotResults('%s.png' % self.result_folder_name) | 330 self.PlotResults('%s.png' % self.result_folder_name) |
| 330 self.Cleanup(); | |
| 331 | 331 |
| 332 class PerformanceTestRunner(TestRunner): | 332 class PerformanceTestRunner(TestRunner): |
| 333 """Super class for all performance testing.""" | 333 """Super class for all performance testing.""" |
| 334 def __init__(self, result_folder_name, platform_list, platform_type): | 334 def __init__(self, result_folder_name, platform_list, platform_type): |
| 335 super(PerformanceTestRunner, self).__init__(result_folder_name, | 335 super(PerformanceTestRunner, self).__init__(result_folder_name, |
| 336 platform_list, GetVersions(), BENCHMARKS) | 336 platform_list, GetVersions(), BENCHMARKS) |
| 337 self.platform_list = platform_list | 337 self.platform_list = platform_list |
| 338 self.platform_type = platform_type | 338 self.platform_type = platform_type |
| 339 | 339 |
| 340 def PlotAllPerf(self, png_filename): | 340 def PlotAllPerf(self, png_filename): |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 | 422 |
| 423 class BrowserPerformanceTestRunner(PerformanceTestRunner): | 423 class BrowserPerformanceTestRunner(PerformanceTestRunner): |
| 424 """Runs performance tests, in the browser.""" | 424 """Runs performance tests, in the browser.""" |
| 425 | 425 |
| 426 def __init__(self, result_folder_name): | 426 def __init__(self, result_folder_name): |
| 427 super(BrowserPerformanceTestRunner, self).__init__( | 427 super(BrowserPerformanceTestRunner, self).__init__( |
| 428 result_folder_name, GetBrowsers(), 'browser') | 428 result_folder_name, GetBrowsers(), 'browser') |
| 429 | 429 |
| 430 def RunTests(self): | 430 def RunTests(self): |
| 431 """Run a performance test in the browser.""" | 431 """Run a performance test in the browser.""" |
| 432 # For the smoke test, just run a simple test, not the actual benchmarks to |
| 433 # ensure we haven't broken the Firefox DOM. |
| 434 |
| 432 os.chdir('frog') | 435 os.chdir('frog') |
| 433 RunCmd(['python', os.path.join('benchmarks', 'make_web_benchmarks.py')]) | 436 RunCmd(['python', os.path.join('benchmarks', 'make_web_benchmarks.py')]) |
| 434 os.chdir('..') | 437 os.chdir('..') |
| 435 | 438 |
| 436 for browser in GetBrowsers(): | 439 for browser in GetBrowsers(): |
| 437 for version in GetVersions(): | 440 for version in GetVersions(): |
| 438 self.trace_file = os.path.join('tools', 'testing', 'perf_testing', | 441 self.trace_file = os.path.join('tools', 'testing', 'perf_testing', |
| 439 self.result_folder_name, | 442 self.result_folder_name, |
| 440 'perf-%s-%s-%s' % (self.cur_time, browser, version)) | 443 'perf-%s-%s-%s' % (self.cur_time, browser, version)) |
| 441 self.AddSvnRevisionToTrace(self.trace_file) | 444 self.AddSvnRevisionToTrace(self.trace_file) |
| 445 bench_page = 'benchmark_page' |
| 446 if not PERFBOT_MODE: |
| 447 bench_page = 'smoketest' |
| 448 pass |
| 442 RunCmd(['python', os.path.join('tools', 'testing', 'run_selenium.py'), | 449 RunCmd(['python', os.path.join('tools', 'testing', 'run_selenium.py'), |
| 443 '--out', os.path.join(os.getcwd(), 'internal', 'browserBenchmarks', | 450 '--out', os.path.join(os.getcwd(), 'internal', 'browserBenchmarks', |
| 444 'benchmark_page_%s.html' % version), '--browser', browser, | 451 '%s_%s.html' % (bench_page, version)), '--browser', browser, |
| 445 '--timeout', '600', '--perf'], self.trace_file, append=True) | 452 '--timeout', '600', '--perf'], self.trace_file, append=True) |
| 446 | 453 |
| 447 def ProcessFile(self, afile): | 454 def ProcessFile(self, afile): |
| 448 """Comb through the html to find the performance results.""" | 455 """Comb through the html to find the performance results.""" |
| 449 parts = afile.split('-') | 456 parts = afile.split('-') |
| 450 browser = parts[2] | 457 browser = parts[2] |
| 451 version = parts[3] | 458 version = parts[3] |
| 452 f = open(os.path.join(self.result_folder_name, afile)) | 459 f = open(os.path.join(self.result_folder_name, afile)) |
| 453 lines = f.readlines() | 460 lines = f.readlines() |
| 454 line = '' | 461 line = '' |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 os.remove(os.path.join(self.result_folder_name, afile)) | 501 os.remove(os.path.join(self.result_folder_name, afile)) |
| 495 else: | 502 else: |
| 496 self.CalculateGeometricMean(browser, version, revision_num) | 503 self.CalculateGeometricMean(browser, version, revision_num) |
| 497 | 504 |
| 498 def WriteHtml(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2, | 505 def WriteHtml(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2, |
| 499 cleanFile=False): | 506 cleanFile=False): |
| 500 #TODO(efortuna) | 507 #TODO(efortuna) |
| 501 pass | 508 pass |
| 502 | 509 |
| 503 | 510 |
| 504 def Cleanup(self): | |
| 505 # Kill the zombie chromedriver processes. | |
| 506 RunCmd(['killall', 'chromedriver']) | |
| 507 | |
| 508 | |
| 509 class BrowserCorrectnessTestRunner(TestRunner): | 511 class BrowserCorrectnessTestRunner(TestRunner): |
| 510 def __init__(self, test_type, result_folder_name): | 512 def __init__(self, test_type, result_folder_name): |
| 511 super(BrowserCorrectnessTestRunner, self).__init__(result_folder_name, | 513 super(BrowserCorrectnessTestRunner, self).__init__(result_folder_name, |
| 512 GetBrowsers(), [FROG], [CORRECTNESS]) | 514 GetBrowsers(), [FROG], [CORRECTNESS]) |
| 513 self.test_type = test_type | 515 self.test_type = test_type |
| 514 | 516 |
| 515 def RunTests(self): | 517 def RunTests(self): |
| 516 """Run a test of the latest svn revision.""" | 518 """Run a test of the latest svn revision.""" |
| 517 for browser in GetBrowsers(): | 519 for browser in GetBrowsers(): |
| 518 current_file = 'correctness%s-%s' % (self.cur_time, browser) | 520 current_file = 'correctness%s-%s' % (self.cur_time, browser) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 f.close() | 559 f.close() |
| 558 | 560 |
| 559 def PlotResults(self, png_filename): | 561 def PlotResults(self, png_filename): |
| 560 first_time = True | 562 first_time = True |
| 561 for browser in GetBrowsers(): | 563 for browser in GetBrowsers(): |
| 562 self.StyleAndSavePerfPlot('Percentage of language tests passing in ' | 564 self.StyleAndSavePerfPlot('Percentage of language tests passing in ' |
| 563 'different browsers', '% of tests passed', 8, 8, 'lower left', | 565 'different browsers', '% of tests passed', 8, 8, 'lower left', |
| 564 png_filename, [browser], [FROG], [CORRECTNESS], first_time) | 566 png_filename, [browser], [FROG], [CORRECTNESS], first_time) |
| 565 first_time = False | 567 first_time = False |
| 566 | 568 |
| 567 def Cleanup(self): | |
| 568 # Kill the zombie chromedriver processes. | |
| 569 RunCmd(['killall', 'chromedriver']) | |
| 570 | 569 |
| 571 class CompileTimeAndSizeTestRunner(TestRunner): | 570 class CompileTimeAndSizeTestRunner(TestRunner): |
| 572 """Run tests to determine how long minfrog takes to compile, and the compiled | 571 """Run tests to determine how long minfrog takes to compile, and the compiled |
| 573 file output size of some benchmarking files.""" | 572 file output size of some benchmarking files.""" |
| 574 def __init__(self, result_folder_name): | 573 def __init__(self, result_folder_name): |
| 575 super(CompileTimeAndSizeTestRunner, self).__init__(result_folder_name, | 574 super(CompileTimeAndSizeTestRunner, self).__init__(result_folder_name, |
| 576 [COMMAND_LINE], [FROG], ['Compiling on Dart VM', 'Bootstrapping', | 575 [COMMAND_LINE], [FROG], ['Compiling on Dart VM', 'Bootstrapping', |
| 577 'minfrog', 'swarm', 'total']) | 576 'minfrog', 'swarm', 'total']) |
| 578 self.failure_threshold = {'Compiling on Dart VM' : 1, 'Bootstrapping' : .5, | 577 self.failure_threshold = {'Compiling on Dart VM' : 1, 'Bootstrapping' : .5, |
| 579 'minfrog' : 100, 'swarm' : 100, 'total' : 100} | 578 'minfrog' : 100, 'swarm' : 100, 'total' : 100} |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 parser.add_option('--language', '-l', dest = 'language', | 688 parser.add_option('--language', '-l', dest = 'language', |
| 690 help = 'Run the language correctness tests', | 689 help = 'Run the language correctness tests', |
| 691 action = 'store_true', default = False) | 690 action = 'store_true', default = False) |
| 692 parser.add_option('--browser-perf', '-b', dest = 'perf', | 691 parser.add_option('--browser-perf', '-b', dest = 'perf', |
| 693 help = 'Run the browser performance tests', | 692 help = 'Run the browser performance tests', |
| 694 action = 'store_true', default = False) | 693 action = 'store_true', default = False) |
| 695 parser.add_option('--forever', '-f', dest = 'continuous', | 694 parser.add_option('--forever', '-f', dest = 'continuous', |
| 696 help = 'Run this script forever, always checking for the next svn ' | 695 help = 'Run this script forever, always checking for the next svn ' |
| 697 'checkin', action = 'store_true', default = False) | 696 'checkin', action = 'store_true', default = False) |
| 698 parser.add_option('--perfbot', '-p', dest = 'perfbot', | 697 parser.add_option('--perfbot', '-p', dest = 'perfbot', |
| 699 help = "Run in perfbot mode. (Generate plots, and remove trace files)", | 698 help = "Run in perfbot mode. (Generate plots, and keep trace files)", |
| 700 action = 'store_true', default = False) | 699 action = 'store_true', default = False) |
| 701 parser.add_option('--verbose', '-v', dest = 'verbose', | 700 parser.add_option('--verbose', '-v', dest = 'verbose', |
| 702 help = 'Print extra debug output', action = 'store_true', default = False) | 701 help = 'Print extra debug output', action = 'store_true', default = False) |
| 703 | 702 |
| 704 args, ignored = parser.parse_args() | 703 args, ignored = parser.parse_args() |
| 705 if not (args.cl or args.size or args.language or args.perf): | 704 if not (args.cl or args.size or args.language or args.perf): |
| 706 args.cl = args.size = args.language = args.perf = True | 705 args.cl = args.size = args.language = args.perf = True |
| 707 return (args.cl, args.size, args.language, args.perf, args.continuous, | 706 return (args.cl, args.size, args.language, args.perf, args.continuous, |
| 708 args.perfbot, args.verbose) | 707 args.perfbot, args.verbose) |
| 709 | 708 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 735 if HasNewCode(): | 734 if HasNewCode(): |
| 736 RunTestSequence(cl, size, language, perf) | 735 RunTestSequence(cl, size, language, perf) |
| 737 else: | 736 else: |
| 738 time.sleep(SLEEP_TIME) | 737 time.sleep(SLEEP_TIME) |
| 739 else: | 738 else: |
| 740 RunTestSequence(cl, size, language, perf) | 739 RunTestSequence(cl, size, language, perf) |
| 741 | 740 |
| 742 if __name__ == '__main__': | 741 if __name__ == '__main__': |
| 743 main() | 742 main() |
| 744 | 743 |
| OLD | NEW |