Home | History | Annotate | Download | only in benchmarks
      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