| 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 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 DART_INSTALL_LOCATION = os.path.join(os.path.dirname(os.path.abspath(__file__)), | 27 DART_INSTALL_LOCATION = os.path.join(os.path.dirname(os.path.abspath(__file__)), |
| 28 '..', '..', '..') | 28 '..', '..', '..') |
| 29 V8_MEAN = 'V8 Mean' | 29 V8_MEAN = 'V8 Mean' |
| 30 FROG_MEAN = 'frog Mean' | 30 FROG_MEAN = 'frog Mean' |
| 31 COMMAND_LINE = 'commandline' | 31 COMMAND_LINE = 'commandline' |
| 32 V8 = 'v8' | 32 V8 = 'v8' |
| 33 FROG = 'frog' | 33 FROG = 'frog' |
| 34 V8_AND_FROG = [V8, FROG] | 34 V8_AND_FROG = [V8, FROG] |
| 35 CORRECTNESS = 'Percent passing' | 35 CORRECTNESS = 'Percent passing' |
| 36 BENCHMARKS = ['Mandelbrot', 'DeltaBlue', 'Richards', 'NBody', | |
| 37 'BinaryTrees', 'Fannkuch', 'Meteor', 'BubbleSort', 'Fibonacci', | |
| 38 'Loop', 'Permute', 'Queens', 'QuickSort', 'Recurse', 'Sieve', 'Sum', | |
| 39 'Tak', 'Takl', 'Towers', 'TreeSort'] | |
| 40 COLORS = ['blue', 'green', 'red', 'cyan', 'magenta', 'black'] | 36 COLORS = ['blue', 'green', 'red', 'cyan', 'magenta', 'black'] |
| 41 GRAPH_OUT_DIR = 'graphs' | 37 GRAPH_OUT_DIR = 'graphs' |
| 42 SLEEP_TIME = 200 | 38 SLEEP_TIME = 200 |
| 43 PERFBOT_MODE = False | 39 PERFBOT_MODE = False |
| 44 VERBOSE = False | 40 VERBOSE = False |
| 45 | 41 |
| 46 """First, some utility methods.""" | 42 """First, some utility methods.""" |
| 47 | 43 |
| 48 def RunCmd(cmd_list, outfile=None, append=False): | 44 def RunCmd(cmd_list, outfile=None, append=False): |
| 49 """Run the specified command and print out any output to stdout. | 45 """Run the specified command and print out any output to stdout. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 if platform.system() == 'Windows': | 138 if platform.system() == 'Windows': |
| 143 browsers += ['ie'] | 139 browsers += ['ie'] |
| 144 return browsers | 140 return browsers |
| 145 | 141 |
| 146 def GetVersions(): | 142 def GetVersions(): |
| 147 if not PERFBOT_MODE: | 143 if not PERFBOT_MODE: |
| 148 return [FROG] | 144 return [FROG] |
| 149 else: | 145 else: |
| 150 return V8_AND_FROG | 146 return V8_AND_FROG |
| 151 | 147 |
| 148 def GetBenchmarks(): |
| 149 if not PERFBOT_MODE: |
| 150 return ['Smoketest'] |
| 151 else: |
| 152 return ['Mandelbrot', 'DeltaBlue', 'Richards', 'NBody', 'BinaryTrees', |
| 153 'Fannkuch', 'Meteor', 'BubbleSort', 'Fibonacci', 'Loop', 'Permute', |
| 154 'Queens', 'QuickSort', 'Recurse', 'Sieve', 'Sum', 'Tak', 'Takl', 'Towers', |
| 155 'TreeSort'] |
| 156 |
| 152 def UploadToAppEngine(): | 157 def UploadToAppEngine(): |
| 153 """Upload our results to our appengine server.""" | 158 """Upload our results to our appengine server.""" |
| 154 # TODO(efortuna): This is the most basic way to get the data up | 159 # TODO(efortuna): This is the most basic way to get the data up |
| 155 # for others to view. Revisit this once we're serving nicer graphs (Google | 160 # for others to view. Revisit this once we're serving nicer graphs (Google |
| 156 # Chart Tools) and from multiple perfbots and once we're in a position to | 161 # Chart Tools) and from multiple perfbots and once we're in a position to |
| 157 # organize the data in a useful manner(!!). | 162 # organize the data in a useful manner(!!). |
| 158 os.chdir(os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing', | 163 os.chdir(os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing', |
| 159 'perf_testing')) | 164 'perf_testing')) |
| 160 shutil.rmtree(os.path.join('appengine', 'static', 'graphs'), | 165 shutil.rmtree(os.path.join('appengine', 'static', 'graphs'), |
| 161 ignore_errors=True) | 166 ignore_errors=True) |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 out.write('<td>%f</td>' % perf) | 294 out.write('<td>%f</td>' % perf) |
| 290 out.write('</tr>\n<tr><td> %s</td>' % label_2) | 295 out.write('</tr>\n<tr><td> %s</td>' % label_2) |
| 291 for perf in dict_2: | 296 for perf in dict_2: |
| 292 out.write('<td>%f</td>' % perf) | 297 out.write('<td>%f</td>' % perf) |
| 293 out.write('</tr> </table>') | 298 out.write('</tr> </table>') |
| 294 | 299 |
| 295 def CalculateGeometricMean(self, platform, frog_or_v8, svn_revision): | 300 def CalculateGeometricMean(self, platform, frog_or_v8, svn_revision): |
| 296 """Calculate the aggregate geometric mean for V8 and frog benchmark sets, | 301 """Calculate the aggregate geometric mean for V8 and frog benchmark sets, |
| 297 given two benchmark dictionaries.""" | 302 given two benchmark dictionaries.""" |
| 298 geo_mean = 0 | 303 geo_mean = 0 |
| 299 for benchmark in BENCHMARKS: | 304 for benchmark in GetBenchmarks(): |
| 300 geo_mean += math.log(self.values_dict[platform][frog_or_v8][benchmark][ | 305 geo_mean += math.log(self.values_dict[platform][frog_or_v8][benchmark][ |
| 301 len(self.values_dict[platform][frog_or_v8][benchmark]) - 1]) | 306 len(self.values_dict[platform][frog_or_v8][benchmark]) - 1]) |
| 302 | 307 |
| 303 mean = V8_MEAN | 308 mean = V8_MEAN |
| 304 if frog_or_v8 == FROG: | 309 if frog_or_v8 == FROG: |
| 305 mean = FROG_MEAN | 310 mean = FROG_MEAN |
| 306 self.values_dict[platform][frog_or_v8][mean] += \ | 311 self.values_dict[platform][frog_or_v8][mean] += \ |
| 307 [math.pow(math.e, geo_mean / len(BENCHMARKS))] | 312 [math.pow(math.e, geo_mean / len(GetBenchmarks()))] |
| 308 self.revision_dict[platform][frog_or_v8][mean] += [svn_revision] | 313 self.revision_dict[platform][frog_or_v8][mean] += [svn_revision] |
| 309 | 314 |
| 310 def Run(self): | 315 def Run(self): |
| 311 """Run the benchmarks/tests from the command line and plot the | 316 """Run the benchmarks/tests from the command line and plot the |
| 312 results.""" | 317 results.""" |
| 313 if PERFBOT_MODE: | 318 if PERFBOT_MODE: |
| 314 plt.cla() # cla = clear current axes | 319 plt.cla() # cla = clear current axes |
| 315 os.chdir(DART_INSTALL_LOCATION) | 320 os.chdir(DART_INSTALL_LOCATION) |
| 316 EnsureOutputDirectory(self.result_folder_name) | 321 EnsureOutputDirectory(self.result_folder_name) |
| 317 EnsureOutputDirectory(GRAPH_OUT_DIR) | 322 EnsureOutputDirectory(GRAPH_OUT_DIR) |
| 318 self.RunTests() | 323 self.RunTests() |
| 319 os.chdir(os.path.join('tools', 'testing', 'perf_testing')) | 324 os.chdir(os.path.join('tools', 'testing', 'perf_testing')) |
| 320 | 325 |
| 321 # TODO(efortuna): You will want to make this only use a subset of the files | 326 # TODO(efortuna): You will want to make this only use a subset of the files |
| 322 # eventually. | 327 # eventually. |
| 323 files = os.listdir(self.result_folder_name) | 328 files = os.listdir(self.result_folder_name) |
| 324 | 329 |
| 325 for afile in files: | 330 for afile in files: |
| 326 if not afile.startswith('.'): | 331 if not afile.startswith('.'): |
| 327 self.ProcessFile(afile) | 332 self.ProcessFile(afile) |
| 328 | 333 |
| 329 if PERFBOT_MODE: | 334 if PERFBOT_MODE: |
| 330 self.PlotResults('%s.png' % self.result_folder_name) | 335 self.PlotResults('%s.png' % self.result_folder_name) |
| 331 | 336 |
| 332 class PerformanceTestRunner(TestRunner): | 337 class PerformanceTestRunner(TestRunner): |
| 333 """Super class for all performance testing.""" | 338 """Super class for all performance testing.""" |
| 334 def __init__(self, result_folder_name, platform_list, platform_type): | 339 def __init__(self, result_folder_name, platform_list, platform_type): |
| 335 super(PerformanceTestRunner, self).__init__(result_folder_name, | 340 super(PerformanceTestRunner, self).__init__(result_folder_name, |
| 336 platform_list, GetVersions(), BENCHMARKS) | 341 platform_list, GetVersions(), GetBenchmarks()) |
| 337 self.platform_list = platform_list | 342 self.platform_list = platform_list |
| 338 self.platform_type = platform_type | 343 self.platform_type = platform_type |
| 339 | 344 |
| 340 def PlotAllPerf(self, png_filename): | 345 def PlotAllPerf(self, png_filename): |
| 341 """Create a plot that shows the performance changes of individual benchmarks | 346 """Create a plot that shows the performance changes of individual benchmarks |
| 342 run by V8 and generated by frog, over svn history.""" | 347 run by V8 and generated by frog, over svn history.""" |
| 343 for benchmark in BENCHMARKS: | 348 for benchmark in GetBenchmarks(): |
| 344 self.StyleAndSavePerfPlot( | 349 self.StyleAndSavePerfPlot( |
| 345 'Performance of %s over time on the %s' % (benchmark, | 350 'Performance of %s over time on the %s' % (benchmark, |
| 346 self.platform_type), 'Speed (bigger = better)', 16, 14, 'lower left', | 351 self.platform_type), 'Speed (bigger = better)', 16, 14, 'lower left', |
| 347 benchmark + png_filename, self.platform_list, GetVersions(), | 352 benchmark + png_filename, self.platform_list, GetVersions(), |
| 348 [benchmark]) | 353 [benchmark]) |
| 349 | 354 |
| 350 def PlotAvgPerf(self, png_filename): | 355 def PlotAvgPerf(self, png_filename): |
| 351 """Generate a plot that shows the performance changes of the geomentric mean | 356 """Generate a plot that shows the performance changes of the geomentric mean |
| 352 of V8 and frog benchmark performance over svn history.""" | 357 of V8 and frog benchmark performance over svn history.""" |
| 353 (title, y_axis, size_x, size_y, loc, filename) = \ | 358 (title, y_axis, size_x, size_y, loc, filename) = \ |
| (...skipping 30 matching lines...) Expand all Loading... |
| 384 f = open(os.path.join(self.result_folder_name, afile)) | 389 f = open(os.path.join(self.result_folder_name, afile)) |
| 385 tabulate_data = False | 390 tabulate_data = False |
| 386 revision_num = 0 | 391 revision_num = 0 |
| 387 for line in f.readlines(): | 392 for line in f.readlines(): |
| 388 if 'Revision' in line: | 393 if 'Revision' in line: |
| 389 revision_num = int(line.split()[1]) | 394 revision_num = int(line.split()[1]) |
| 390 elif 'Benchmark' in line: | 395 elif 'Benchmark' in line: |
| 391 tabulate_data = True | 396 tabulate_data = True |
| 392 elif tabulate_data: | 397 elif tabulate_data: |
| 393 tokens = line.split() | 398 tokens = line.split() |
| 394 if len(tokens) < 4 or tokens[0] not in BENCHMARKS: | 399 if len(tokens) < 4 or tokens[0] not in GetBenchmarks(): |
| 395 #Done tabulating data. | 400 #Done tabulating data. |
| 396 break | 401 break |
| 397 v8_value = float(tokens[1]) | 402 v8_value = float(tokens[1]) |
| 398 frog_value = float(tokens[3]) | 403 frog_value = float(tokens[3]) |
| 399 if v8_value == 0 or frog_value == 0: | 404 if v8_value == 0 or frog_value == 0: |
| 400 #Then there was an error when this performance test was run. Do not | 405 #Then there was an error when this performance test was run. Do not |
| 401 #count it in our numbers. | 406 #count it in our numbers. |
| 402 return | 407 return |
| 403 benchmark = tokens[0] | 408 benchmark = tokens[0] |
| 404 self.revision_dict[COMMAND_LINE][V8][benchmark] += [revision_num] | 409 self.revision_dict[COMMAND_LINE][V8][benchmark] += [revision_num] |
| (...skipping 21 matching lines...) Expand all Loading... |
| 426 def __init__(self, result_folder_name): | 431 def __init__(self, result_folder_name): |
| 427 super(BrowserPerformanceTestRunner, self).__init__( | 432 super(BrowserPerformanceTestRunner, self).__init__( |
| 428 result_folder_name, GetBrowsers(), 'browser') | 433 result_folder_name, GetBrowsers(), 'browser') |
| 429 | 434 |
| 430 def RunTests(self): | 435 def RunTests(self): |
| 431 """Run a performance test in the browser.""" | 436 """Run a performance test in the browser.""" |
| 432 # For the smoke test, just run a simple test, not the actual benchmarks to | 437 # For the smoke test, just run a simple test, not the actual benchmarks to |
| 433 # ensure we haven't broken the Firefox DOM. | 438 # ensure we haven't broken the Firefox DOM. |
| 434 | 439 |
| 435 os.chdir('frog') | 440 os.chdir('frog') |
| 436 RunCmd(['python', os.path.join('benchmarks', 'make_web_benchmarks.py')]) | 441 if PERFBOT_MODE: |
| 442 RunCmd(['python', os.path.join('benchmarks', 'make_web_benchmarks.py')]) |
| 443 else: |
| 444 RunCmd(['./minfrog', '--out=../tools/testing/perf_testing/smoketest/' + \ |
| 445 'smoketest_frog.js', '--libdir=%s/lib' % os.getcwd(), |
| 446 '--compile-only', '../tools/testing/perf_testing/smoketest/' + \ |
| 447 'dartWebBase.dart']) |
| 437 os.chdir('..') | 448 os.chdir('..') |
| 438 | 449 |
| 439 for browser in GetBrowsers(): | 450 for browser in GetBrowsers(): |
| 440 for version in GetVersions(): | 451 for version in GetVersions(): |
| 441 self.trace_file = os.path.join('tools', 'testing', 'perf_testing', | 452 self.trace_file = os.path.join('tools', 'testing', 'perf_testing', |
| 442 self.result_folder_name, | 453 self.result_folder_name, |
| 443 'perf-%s-%s-%s' % (self.cur_time, browser, version)) | 454 'perf-%s-%s-%s' % (self.cur_time, browser, version)) |
| 444 self.AddSvnRevisionToTrace(self.trace_file) | 455 self.AddSvnRevisionToTrace(self.trace_file) |
| 445 bench_page = 'benchmark_page' | 456 file_path = os.path.join(os.getcwd(), 'internal', 'browserBenchmarks', |
| 457 'benchmark_page_%s.html' % version) |
| 446 if not PERFBOT_MODE: | 458 if not PERFBOT_MODE: |
| 447 bench_page = 'smoketest' | 459 file_path = os.path.join(os.getcwd(), 'tools', 'testing', |
| 448 pass | 460 'perf_testing', 'smoketest', 'smoketest_%s.html' % version) |
| 449 RunCmd(['python', os.path.join('tools', 'testing', 'run_selenium.py'), | 461 RunCmd(['python', os.path.join('tools', 'testing', 'run_selenium.py'), |
| 450 '--out', os.path.join(os.getcwd(), 'internal', 'browserBenchmarks', | 462 '--out', file_path, '--browser', browser, |
| 451 '%s_%s.html' % (bench_page, version)), '--browser', browser, | |
| 452 '--timeout', '600', '--perf'], self.trace_file, append=True) | 463 '--timeout', '600', '--perf'], self.trace_file, append=True) |
| 453 | 464 |
| 454 def ProcessFile(self, afile): | 465 def ProcessFile(self, afile): |
| 455 """Comb through the html to find the performance results.""" | 466 """Comb through the html to find the performance results.""" |
| 456 parts = afile.split('-') | 467 parts = afile.split('-') |
| 457 browser = parts[2] | 468 browser = parts[2] |
| 458 version = parts[3] | 469 version = parts[3] |
| 459 f = open(os.path.join(self.result_folder_name, afile)) | 470 f = open(os.path.join(self.result_folder_name, afile)) |
| 460 lines = f.readlines() | 471 lines = f.readlines() |
| 461 line = '' | 472 line = '' |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 if HasNewCode(): | 745 if HasNewCode(): |
| 735 RunTestSequence(cl, size, language, perf) | 746 RunTestSequence(cl, size, language, perf) |
| 736 else: | 747 else: |
| 737 time.sleep(SLEEP_TIME) | 748 time.sleep(SLEEP_TIME) |
| 738 else: | 749 else: |
| 739 RunTestSequence(cl, size, language, perf) | 750 RunTestSequence(cl, size, language, perf) |
| 740 | 751 |
| 741 if __name__ == '__main__': | 752 if __name__ == '__main__': |
| 742 main() | 753 main() |
| 743 | 754 |
| OLD | NEW |