summaryrefslogtreecommitdiffstats
path: root/third_party/WebKit/LayoutTests/fast/harness/perftests/perf-runner-compute-statistics.html
blob: 40f1cc8d19ce509aa3a12b41f87252653c0717cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test.js"></script>
<script src="../../../../PerformanceTests/resources/runner.js"></script>
<script type="text/javascript">
var alternateComputeStatistics = {
    min: function(array) {
        return Math.min.apply(Math, array);
    },
    max: function(array) {
        return Math.max.apply(Math, array);
    },
    median: function(originalData) {
        // don't want side effects on the input array, so...
        var array = originalData.slice(0);
        array.sort(function(a,b) { return a - b; });
        var mid = Math.floor(array.length / 2);
        if (array.length % 2)
            return array[mid];
        else
            return (array[mid-1] + array[mid]) / 2;
    },
    mean: function(array) {
        return alternateComputeStatistics.sum(array)/array.length;
    },
    sum: function(array) {
        var total = 0;
        for (var index in array)
            total += array[index];
        return total;
    },
    variance: function(array) {
        var mean = alternateComputeStatistics.mean(array);
        var sumOfSquaredDiffs = 0;
        for (var index in array) {
            var squaredDiff = array[index] - mean;
            sumOfSquaredDiffs += squaredDiff * squaredDiff;
        };
        return sumOfSquaredDiffs / (array.length - 1);
    },
    stdev: function(array) {
        return Math.sqrt(alternateComputeStatistics.variance(array));
    }
};
</script>
</head>
<body>

<div id="description"></div>

<script type="text/javascript">
description("This test verifies PerfTestRunner.computeStatistics(), " +
            "including: min, max, median, mean, variance, and stdev.");
</script>

<div id="console"></div>

<script type="text/javascript">
var data = [];
var stats = [];

data = [0, 0, 0, 0, 0];
debug("Ensure no latent divide by 0's for an odd number of elements.");
debug("data = " + JSON.stringify(data));
stats = PerfTestRunner.computeStatistics(data);
shouldEvaluateTo("stats.min", 0);
shouldEvaluateTo("stats.max", 0);
shouldEvaluateTo("stats.median", 0);
shouldEvaluateTo("stats.mean", 0);
shouldEvaluateTo("stats.variance", 0);
shouldEvaluateTo("stats.stdev", 0);
debug("");

data = [1, 10, 2, 20, 5];
debug("This test will catch if any order dependencies in the data, such as");
debug("needing to be numerically sorted, are not resolved by the algorithm.");
debug("This variant covers an odd number of elements.");
debug("data = " + JSON.stringify(data));
stats = PerfTestRunner.computeStatistics(data);
// hand calculated
shouldEvaluateTo("stats.min", 1);
shouldEvaluateTo("stats.max", 20);
shouldEvaluateTo("stats.median", 5);
shouldEvaluateTo("stats.mean", (38/5));
// using alternate implementation
shouldEvaluateTo("stats.min", alternateComputeStatistics.min(data));
shouldEvaluateTo("stats.max", alternateComputeStatistics.max(data));
shouldEvaluateTo("stats.median", alternateComputeStatistics.median(data));
shouldEvaluateTo("stats.mean", alternateComputeStatistics.mean(data));
shouldBeCloseTo("stats.variance", alternateComputeStatistics.variance(data), 0.0001);
shouldBeCloseTo("stats.stdev", alternateComputeStatistics.stdev(data), 0.0001);
debug("");

data = [-1, -10, -2, -20, -5];
debug("This test will catch if any order dependencies in the data, such as");
debug("needing to be numerically sorted, are not resolved by the algorithm.");
debug("This variant covers an odd number of elements, and negative values.");
debug("data = " + JSON.stringify(data));
stats = PerfTestRunner.computeStatistics(data);
// hand calculated
shouldEvaluateTo("stats.min", -20);
shouldEvaluateTo("stats.max", -1);
shouldEvaluateTo("stats.median", -5);
shouldEvaluateTo("stats.mean", (-38/5));
// using alternate implementation
shouldEvaluateTo("stats.min", alternateComputeStatistics.min(data));
shouldEvaluateTo("stats.max", alternateComputeStatistics.max(data));
shouldEvaluateTo("stats.median", alternateComputeStatistics.median(data));
shouldEvaluateTo("stats.mean", alternateComputeStatistics.mean(data));
shouldBeCloseTo("stats.variance", alternateComputeStatistics.variance(data), 0.0001);
shouldBeCloseTo("stats.stdev", alternateComputeStatistics.stdev(data), 0.0001);
debug("");

data = [0, 0, 0, 0];
debug("Ensure no latent divide by 0's for an even number of elements.");
debug("data = " + JSON.stringify(data));
stats = PerfTestRunner.computeStatistics(data);
shouldEvaluateTo("stats.median", 0);
debug("");

data = [1, 10, 2, 20, 5, 6];
debug("This test verifies that median is handled correctly for");
debug("an even number of elements.");
debug("data = " + JSON.stringify(data));
stats = PerfTestRunner.computeStatistics(data);
shouldEvaluateTo("stats.median", 5.5);
shouldEvaluateTo("stats.median", alternateComputeStatistics.median(data));
debug("");

data = [-1, -10, -2, -20, -5, -6];
debug("This test verifies that median is handled correctly for");
debug("an even number of elements, including negative numbers.");
debug("data = " + JSON.stringify(data));
stats = PerfTestRunner.computeStatistics(data);
shouldEvaluateTo("stats.median", -5.5);
shouldEvaluateTo("stats.median", alternateComputeStatistics.median(data));
debug("");

// runner.js marks this as an async test so we need to call notifyDone.
if (window.testRunner)
    testRunner.notifyDone();
</script>

</body>
</html>