1 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 import collections 5 import json 6 import os 7 8 from metrics import power 9 from telemetry import benchmark 10 from telemetry.page import page_set 11 from telemetry.page import page_test 12 from telemetry.value import list_of_scalar_values 13 14 15 _URL = 'http://www.webkit.org/perf/sunspider-1.0.2/sunspider-1.0.2/driver.html' 16 17 DESCRIPTIONS = { 18 '3d-cube': 19 'Pure JavaScript computations of the kind you might use to do 3d ' 20 'rendering, but without the rendering. This ends up mostly hitting ' 21 'floating point math and array access.', 22 '3d-morph': 23 'Pure JavaScript computations of the kind you might use to do 3d ' 24 'rendering, but without the rendering. This ends up mostly hitting ' 25 'floating point math and array access.', 26 '3d-raytrace': 27 'Pure JavaScript computations of the kind you might use to do 3d ' 28 'rendering, but without the rendering. This ends up mostly hitting ' 29 'floating point math and array access.', 30 'access-binary-trees': 'Array, object property and variable access.', 31 'access-fannkuch': 'Array, object property and variable access.', 32 'access-nbody': 'Array, object property and variable access.', 33 'access-nsieve': 'Array, object property and variable access.', 34 'bitops-3bit-bits-in-byte': 35 'Bitwise operations, these can be useful for various things ' 36 'including games, mathematical computations, and various kinds of ' 37 'encoding/decoding. It\'s also the only kind of math in JavaScript ' 38 'that is done as integer, not floating point.', 39 'bitops-bits-in-byte': 40 'Bitwise operations, these can be useful for various things ' 41 'including games, mathematical computations, and various kinds of ' 42 'encoding/decoding. It\'s also the only kind of math in JavaScript ' 43 'that is done as integer, not floating point.', 44 'bitops-bitwise-and': 45 'Bitwise operations, these can be useful for various things ' 46 'including games, mathematical computations, and various kinds of ' 47 'encoding/decoding. It\'s also the only kind of math in JavaScript ' 48 'that is done as integer, not floating point.', 49 'bitops-nsieve-bits': 50 'Bitwise operations, these can be useful for various things ' 51 'including games, mathematical computations, and various kinds of ' 52 'encoding/decoding. It\'s also the only kind of math in JavaScript ' 53 'that is done as integer, not floating point.', 54 'controlflow-recursive': 55 'Control flow constructs (looping, recursion, conditionals). Right ' 56 'now it mostly covers recursion, as the others are pretty well covered ' 57 'by other tests.', 58 'crypto-aes': 'Real cryptography code related to AES.', 59 'crypto-md5': 'Real cryptography code related to MD5.', 60 'crypto-sha1': 'Real cryptography code related to SHA1.', 61 'date-format-tofte': 'Performance of JavaScript\'s "date" objects.', 62 'date-format-xparb': 'Performance of JavaScript\'s "date" objects.', 63 'math-cordic': 'Various mathematical type computations.', 64 'math-partial-sums': 'Various mathematical type computations.', 65 'math-spectral-norm': 'Various mathematical type computations.', 66 'regexp-dna': 'Regular expressions performance.', 67 'string-base64': 'String processing.', 68 'string-fasta': 'String processing', 69 'string-tagcloud': 'String processing code to generate a giant "tagcloud".', 70 'string-unpack-code': 'String processing code to extracting compressed JS.', 71 'string-validate-input': 'String processing.', 72 } 73 74 75 class _SunspiderMeasurement(page_test.PageTest): 76 def __init__(self): 77 super(_SunspiderMeasurement, self).__init__() 78 self._power_metric = None 79 80 def CustomizeBrowserOptions(self, options): 81 power.PowerMetric.CustomizeBrowserOptions(options) 82 83 def WillStartBrowser(self, platform): 84 self._power_metric = power.PowerMetric(platform) 85 86 def DidNavigateToPage(self, page, tab): 87 self._power_metric.Start(page, tab) 88 89 def ValidateAndMeasurePage(self, page, tab, results): 90 tab.WaitForJavaScriptExpression( 91 'window.location.pathname.indexOf("results.html") >= 0' 92 '&& typeof(output) != "undefined"', 300) 93 94 self._power_metric.Stop(page, tab) 95 self._power_metric.AddResults(tab, results) 96 97 js_get_results = 'JSON.stringify(output);' 98 js_results = json.loads(tab.EvaluateJavaScript(js_get_results)) 99 100 # Below, r is a map of benchmark names to lists of result numbers, 101 # and totals is a list of totals of result numbers. 102 # js_results is: formatted like this: 103 # [ 104 # {'3d-cube': v1, '3d-morph': v2, ...}, 105 # {'3d-cube': v3, '3d-morph': v4, ...}, 106 # ... 107 # ] 108 r = collections.defaultdict(list) 109 totals = [] 110 for result in js_results: 111 total = 0 112 for key, value in result.iteritems(): 113 r[key].append(value) 114 total += value 115 totals.append(total) 116 for key, values in r.iteritems(): 117 results.AddValue(list_of_scalar_values.ListOfScalarValues( 118 results.current_page, key, 'ms', values, important=False, 119 description=DESCRIPTIONS.get(key))) 120 results.AddValue(list_of_scalar_values.ListOfScalarValues( 121 results.current_page, 'Total', 'ms', totals, 122 description='Totals of run time for each different type of benchmark ' 123 'in sunspider')) 124 125 126 class Sunspider(benchmark.Benchmark): 127 """Apple's SunSpider JavaScript benchmark.""" 128 test = _SunspiderMeasurement 129 130 def CreatePageSet(self, options): 131 ps = page_set.PageSet( 132 archive_data_file='../page_sets/data/sunspider.json', 133 make_javascript_deterministic=False, 134 file_path=os.path.abspath(__file__)) 135 ps.AddPageWithDefaultRunNavigate(_URL) 136 return ps 137