2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Mozilla Foundation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 var count
= output
.length
;
30 itemTotals
.length
= count
;
33 var categoryTotals
= {};
34 var testTotalsByCategory
= {};
37 var categoryMeans
= {};
38 var testMeansByCategory
= {};
41 var categoryStdDevs
= {};
42 var testStdDevsByCategory
= {};
45 var categoryStdErrs
= {};
46 var testStdErrsByCategory
= {};
50 itemTotals
= {total
: []};
52 for (var i
= 0; i
< categories
.length
; i
++) {
53 var category
= categories
[i
];
54 itemTotals
[category
] = [];
55 categoryTotals
[category
] = 0;
56 testTotalsByCategory
[category
] = {};
57 categoryMeans
[category
] = 0;
58 testMeansByCategory
[category
] = {};
59 categoryStdDevs
[category
] = 0;
60 testStdDevsByCategory
[category
] = {};
61 categoryStdErrs
[category
] = 0;
62 testStdErrsByCategory
[category
] = {};
65 for (var i
= 0; i
< tests
.length
; i
++) {
67 itemTotals
[test
] = [];
68 var category
= test
.replace(/-.*/, "");
69 testTotalsByCategory
[category
][test
] = 0;
70 testMeansByCategory
[category
][test
] = 0;
71 testStdDevsByCategory
[category
][test
] = 0;
72 testStdErrsByCategory
[category
][test
] = 0;
75 for (var i
= 0; i
< count
; i
++) {
76 itemTotals
["total"][i
] = 0;
77 for (var category
in categoryTotals
) {
78 itemTotals
[category
][i
] = 0;
79 for (var test
in testTotalsByCategory
[category
]) {
80 itemTotals
[test
][i
] = 0;
86 function computeItemTotals()
88 for (var i
= 0; i
< output
.length
; i
++) {
89 var result
= output
[i
];
90 for (var test
in result
) {
91 var time
= result
[test
];
92 var category
= test
.replace(/-.*/, "");
93 itemTotals
["total"][i
] += time
;
94 itemTotals
[category
][i
] += time
;
95 itemTotals
[test
][i
] += time
;
100 function computeTotals()
102 for (var i
= 0; i
< output
.length
; i
++) {
103 var result
= output
[i
];
104 for (var test
in result
) {
105 var time
= result
[test
];
106 var category
= test
.replace(/-.*/, "");
108 categoryTotals
[category
] += time
;
109 testTotalsByCategory
[category
][test
] += time
;
114 function computeMeans()
116 mean
= total
/ count
;
117 for (var category
in categoryTotals
) {
118 categoryMeans
[category
] = categoryTotals
[category
] / count
;
119 for (var test
in testTotalsByCategory
[category
]) {
120 testMeansByCategory
[category
][test
] = testTotalsByCategory
[category
][test
] / count
;
125 function standardDeviation(mean
, items
)
127 var deltaSquaredSum
= 0;
128 for (var i
= 0; i
< items
.length
; i
++) {
129 var delta
= items
[i
] - mean
;
130 deltaSquaredSum
+= delta
* delta
;
132 variance
= deltaSquaredSum
/ (items
.length
- 1);
133 return Math
.sqrt(variance
);
136 function computeStdDevs()
138 stdDev
= standardDeviation(mean
, itemTotals
["total"]);
139 for (var category
in categoryStdDevs
) {
140 categoryStdDevs
[category
] = standardDeviation(categoryMeans
[category
], itemTotals
[category
]);
142 for (var category
in categoryStdDevs
) {
143 for (var test
in testStdDevsByCategory
[category
]) {
144 testStdDevsByCategory
[category
][test
] = standardDeviation(testMeansByCategory
[category
][test
], itemTotals
[test
]);
149 function computeStdErrors()
151 var sqrtCount
= Math
.sqrt(count
);
153 stdErr
= stdDev
/ sqrtCount
;
154 for (var category
in categoryStdErrs
) {
155 categoryStdErrs
[category
] = categoryStdDevs
[category
] / sqrtCount
;
157 for (var category
in categoryStdDevs
) {
158 for (var test
in testStdErrsByCategory
[category
]) {
159 testStdErrsByCategory
[category
][test
] = testStdDevsByCategory
[category
][test
] / sqrtCount
;
165 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];
166 var tMax
= tDistribution
.length
;
173 return tDistribution
[n
];
177 function formatResult(meanWidth
, mean
, stdErr
, n
)
179 var meanString
= mean
.toFixed(1).toString();
180 while (meanString
.length
< meanWidth
) {
181 meanString
= " " + meanString
;
185 return meanString
+ "ms";
187 return meanString
+ "ms +/- " + ((tDist(n
) * stdErr
/ mean
) * 100).toFixed(1) + "%";
190 function computeLabelWidth()
192 var width
= "Total".length
;
193 for (var category
in categoryMeans
) {
194 if (category
.length
+ 2 > width
)
195 width
= category
.length
+ 2;
197 for (var i
= 0; i
< tests
.length
; i
++) {
198 var shortName
= tests
[i
].replace(/^[^-]*-/, "");
199 if (shortName
.length
+ 4 > width
)
200 width
= shortName
.length
+ 4;
206 function computeMeanWidth()
208 var width
= mean
.toFixed(1).toString().length
;
209 for (var category
in categoryMeans
) {
210 var candidate
= categoryMeans
[category
].toFixed(2).toString().length
;
211 if (candidate
> width
)
213 for (var test
in testMeansByCategory
[category
]) {
214 var candidate
= testMeansByCategory
[category
][test
].toFixed(2).toString().length
;
215 if (candidate
> width
)
223 if (!this['explanations'])
224 var explanations
= {};
226 function resultLine(labelWidth
, indent
, label
, meanWidth
, mean
, stdErr
)
229 for (i
= 0; i
< indent
; i
++) {
233 if (label
in explanations
)
234 result
+= "<a href='" + explanations
[label
] + "'>" + label
+ "</a>: ";
236 result
+= label
+ ": ";
238 for (i
= 0; i
< (labelWidth
- (label
.length
+ indent
)); i
++) {
242 return result
+ formatResult(meanWidth
, mean
, stdErr
, count
);
245 function printOutput()
247 var labelWidth
= computeLabelWidth();
248 var meanWidth
= computeMeanWidth();
251 print("===============================================");
255 print("RESULTS (means and 95% confidence intervals)");
256 print("-----------------------------------------------");
257 print(resultLine(labelWidth
, 0, "Total", meanWidth
, mean
, stdErr
));
258 print("-----------------------------------------------");
259 for (var category
in categoryMeans
) {
261 print(resultLine(labelWidth
, 2, category
, meanWidth
, categoryMeans
[category
], categoryStdErrs
[category
]));
262 for (var test
in testMeansByCategory
[category
]) {
263 var shortName
= test
.replace(/^[^-]*-/, "");
264 print(resultLine(labelWidth
, 4, shortName
, meanWidth
, testMeansByCategory
[category
][test
], testStdErrsByCategory
[category
][test
]));
276 automation
.setDone();