Home | History | Annotate | Download | only in resources
      1 /*
      2  * Copyright (C) 2007 Apple Inc.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 var count = output.length;
     27 
     28 var itemTotals = {};
     29 itemTotals.length = count;
     30 
     31 var total = 0;
     32 var categoryTotals = {};
     33 var testTotalsByCategory = {};
     34 
     35 var mean = 0;
     36 var categoryMeans = {};
     37 var testMeansByCategory = {};
     38 
     39 var stdDev = 0;
     40 var categoryStdDevs = {};
     41 var testStdDevsByCategory = {};
     42 
     43 var stdErr = 0;
     44 var categoryStdErrs = {};
     45 var testStdErrsByCategory = {};
     46 
     47 function initialize()
     48 {
     49     itemTotals = {total: []};
     50 
     51     for (var i = 0; i < categories.length; i++) {
     52         var category = categories[i];
     53         itemTotals[category] = [];
     54         categoryTotals[category] = 0;
     55         testTotalsByCategory[category] = {};
     56         categoryMeans[category] = 0;
     57         testMeansByCategory[category] = {};
     58         categoryStdDevs[category] = 0;
     59         testStdDevsByCategory[category] = {};
     60         categoryStdErrs[category] = 0;
     61         testStdErrsByCategory[category] = {};
     62     }
     63 
     64     for (var i = 0; i < tests.length; i++) {
     65         var test = tests[i];
     66         itemTotals[test] = [];
     67         var category = test.replace(/-.*/, "");
     68         testTotalsByCategory[category][test] = 0;
     69         testMeansByCategory[category][test] = 0;
     70         testStdDevsByCategory[category][test] = 0;
     71         testStdErrsByCategory[category][test] = 0;
     72     }
     73 
     74     for (var i = 0; i < count; i++) {
     75         itemTotals["total"][i] = 0;
     76         for (var category in categoryTotals) {
     77             itemTotals[category][i] = 0;
     78             for (var test in testTotalsByCategory[category]) {
     79                 itemTotals[test][i] = 0;
     80             }
     81         }
     82     }
     83 }
     84 
     85 function computeItemTotals()
     86 {
     87     for (var i = 0; i < output.length; i++) {
     88         var result = output[i];
     89         for (var test in result) {
     90             var time = result[test];
     91             var category = test.replace(/-.*/, "");
     92             itemTotals["total"][i] += time;
     93             itemTotals[category][i] += time;
     94             itemTotals[test][i] += time;
     95         }
     96     }
     97 }
     98 
     99 function computeTotals()
    100 {
    101     for (var i = 0; i < output.length; i++) {
    102         var result = output[i];
    103         for (var test in result) {
    104             var time = result[test];
    105             var category = test.replace(/-.*/, "");
    106             total += time;
    107             categoryTotals[category] += time;
    108             testTotalsByCategory[category][test] += time;
    109         }
    110     }
    111 }
    112 
    113 function computeMeans()
    114 {
    115     mean = total / count;
    116     for (var category in categoryTotals) {
    117         categoryMeans[category] = categoryTotals[category] / count;
    118         for (var test in testTotalsByCategory[category]) {
    119             testMeansByCategory[category][test] = testTotalsByCategory[category][test] / count;
    120         }
    121     }
    122 }
    123 
    124 function standardDeviation(mean, items)
    125 {
    126     var deltaSquaredSum = 0;
    127     for (var i = 0; i < items.length; i++) {
    128         var delta = items[i] - mean;
    129         deltaSquaredSum += delta * delta;
    130     }
    131     variance = deltaSquaredSum / (items.length - 1);
    132     return Math.sqrt(variance);
    133 }
    134 
    135 function computeStdDevs()
    136 {
    137     stdDev = standardDeviation(mean, itemTotals["total"]);
    138     for (var category in categoryStdDevs) {
    139         categoryStdDevs[category] = standardDeviation(categoryMeans[category], itemTotals[category]);
    140     }
    141     for (var category in categoryStdDevs) {
    142         for (var test in testStdDevsByCategory[category]) {
    143             testStdDevsByCategory[category][test] = standardDeviation(testMeansByCategory[category][test], itemTotals[test]);
    144         }
    145     }
    146 }
    147 
    148 function computeStdErrors()
    149 {
    150     var sqrtCount = Math.sqrt(count);
    151 
    152     stdErr = stdDev / sqrtCount;
    153     for (var category in categoryStdErrs) {
    154         categoryStdErrs[category] = categoryStdDevs[category] / sqrtCount;
    155     }
    156     for (var category in categoryStdDevs) {
    157         for (var test in testStdErrsByCategory[category]) {
    158             testStdErrsByCategory[category][test] = testStdDevsByCategory[category][test] / sqrtCount;
    159         }
    160     }
    161 
    162 }
    163 
    164 var tDistribution = [NaN, NaN, 12.71, 4.30, 3.18, 2.78, 2.57, 2.45, 2.36, 2.31, 2.26, 2.23, 2.20, 2.18, 2.16, 2.14, 2.13, 2.12, 2.11, 2.10, 2.09, 2.09, 2.08, 2.07, 2.07, 2.06, 2.06, 2.06, 2.05, 2.05, 2.05, 2.04, 2.04, 2.04, 2.03, 2.03, 2.03, 2.03, 2.03, 2.02, 2.02, 2.02, 2.02, 2.02, 2.02, 2.02, 2.01, 2.01, 2.01, 2.01, 2.01, 2.01, 2.01, 2.01, 2.01, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.99, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.98, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.97, 1.96];
    165 var tMax = tDistribution.length;
    166 var tLimit = 1.96;
    167 
    168 function tDist(n)
    169 {
    170     if (n > tMax)
    171         return tLimit;
    172     return tDistribution[n];
    173 }
    174 
    175 
    176 function formatResult(meanWidth, mean, stdErr, n)
    177 {
    178     var meanString = mean.toFixed(1).toString();
    179     while (meanString.length < meanWidth) {
    180         meanString = " " + meanString;
    181     }
    182 
    183     if (n == 1)
    184         return meanString + "ms";
    185 
    186     return meanString + "ms +/- " + ((tDist(n) * stdErr / mean) * 100).toFixed(1) + "%";
    187 }
    188 
    189 function computeLabelWidth()
    190 {
    191     var width = "Total".length;
    192     for (var category in categoryMeans) {
    193         if (category.length + 2 > width)
    194             width = category.length + 2;
    195     }
    196     for (var i = 0; i < tests.length; i++) {
    197         var shortName = tests[i].replace(/^[^-]*-/, "");
    198         if (shortName.length + 4 > width)
    199             width = shortName.length + 4;
    200     }
    201 
    202     return width;
    203 }
    204 
    205 function computeMeanWidth()
    206 {
    207     var width = mean.toFixed(1).toString().length;
    208     for (var category in categoryMeans) {
    209         var candidate = categoryMeans[category].toFixed(2).toString().length;
    210         if (candidate > width)
    211             width = candidate;
    212         for (var test in testMeansByCategory[category]) {
    213             var candidate = testMeansByCategory[category][test].toFixed(2).toString().length;
    214             if (candidate > width)
    215                 width = candidate;
    216         }
    217     }
    218 
    219     return width;
    220 }
    221 
    222 function resultLine(labelWidth, indent, label, meanWidth, mean, stdErr)
    223 {
    224     var result = "";
    225     for (i = 0; i < indent; i++) {
    226         result += " ";
    227     }
    228 
    229     result += label + ": ";
    230 
    231     for (i = 0; i < (labelWidth - (label.length + indent)); i++) {
    232         result += " ";
    233     }
    234 
    235     return result + formatResult(meanWidth, mean, stdErr, count);
    236 }
    237 
    238 function printOutput()
    239 {
    240     var labelWidth = computeLabelWidth();
    241     var meanWidth = computeMeanWidth();
    242 
    243     print("\n");
    244     print("============================================");
    245     if (count == 1)
    246         print("RESULTS");
    247     else
    248         print("RESULTS (means and 95% confidence intervals)");
    249     print("--------------------------------------------");
    250     print(resultLine(labelWidth, 0, "Total", meanWidth, mean, stdErr));
    251     print("--------------------------------------------");
    252     for (var category in categoryMeans) {
    253         print("");
    254         print(resultLine(labelWidth, 2, category, meanWidth, categoryMeans[category], categoryStdErrs[category]));
    255         for (var test in testMeansByCategory[category]) {
    256             var shortName = test.replace(/^[^-]*-/, "");
    257             print(resultLine(labelWidth, 4, shortName, meanWidth, testMeansByCategory[category][test], testStdErrsByCategory[category][test]));
    258         }
    259     }
    260 }
    261 
    262 initialize();
    263 computeItemTotals();
    264 computeTotals();
    265 computeMeans();
    266 computeStdDevs();
    267 computeStdErrors();
    268 printOutput();
    269