Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 4614cc0

Browse files
committed
feat(benchmark): calculate relative margin of error and simplify report
1 parent bd17bbe commit 4614cc0

File tree

3 files changed

+46
-82
lines changed

3 files changed

+46
-82
lines changed

benchmark/web/bp.js

Lines changed: 26 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,27 @@ bp.runState = {
1313
timesPerAction: {}
1414
};
1515

16-
bp.Statistics.getStabilityOfSample = function (sample, confidenceRange) {
17-
var inRange = 0;
18-
sample.forEach(function(x) {
19-
inRange += x <= confidenceRange[1] && x >= confidenceRange[0] ? 1 : 0;
20-
})
21-
return Math.round((inRange / sample.length) * 100) / 100;
22-
23-
};
24-
25-
bp.Statistics.getConfidenceRange = function(mean, confidenceInterval) {
26-
return [
27-
Math.round((mean - confidenceInterval) * 100) / 100,
28-
Math.round((mean + confidenceInterval) * 100) / 100
29-
];
30-
};
16+
bp.Statistics.getMean = function (sample) {
17+
var total = 0;
18+
sample.forEach(function(x) { total += x; });
19+
return total / sample.length;
20+
}
3121

3222
bp.Statistics.calculateConfidenceInterval = function(standardDeviation, sampleSize) {
3323
var standardError = standardDeviation / Math.sqrt(sampleSize);
34-
var marginOfError = bp.Statistics.criticalValue * standardError;
35-
marginOfError = Math.round(marginOfError * 100) / 100;
36-
return marginOfError;
24+
return bp.Statistics.criticalValue * standardError;
3725
};
3826

39-
bp.Statistics.calculateStandardDeviation = function(sample) {
40-
var mean = 0;
41-
var deviation = 0;
42-
sample.forEach(function(x) {
43-
mean += x;
44-
});
45-
mean = mean / sample.length;
27+
bp.Statistics.calculateRelativeMarginOfError = function (marginOfError, mean) {
28+
/*
29+
* Converts absolute margin of error to a relative margin of error by
30+
* converting it to a percentage of the mean.
31+
*/
32+
return (marginOfError / mean);
33+
};
4634

35+
bp.Statistics.calculateStandardDeviation = function(sample, mean) {
36+
var deviation = 0;
4737
sample.forEach(function(x) {
4838
deviation += Math.pow(x - mean, 2);
4939
});
@@ -194,27 +184,20 @@ bp.generateReportModel = function (rawModel) {
194184
rawModel.gcTimes = rawModel.gcTimes.join('<br>'),
195185
rawModel.garbageTimes = rawModel.garbageTimes.join('<br>'),
196186
rawModel.retainedTimes = rawModel.retainedTimes.join('<br>')
187+
rawModel.timesConfidenceInterval = (rawModel.timesConfidenceInterval || 0).toFixed(2);
197188
return rawModel;
198189
};
199190

200191
bp.generateReportPartial = function(model) {
201192
return bp.infoTemplate(model);
202193
};
203194

204-
bp.getAverage = function (times, gcTimes, garbageTimes, retainedTimes) {
205-
var timesAvg = 0;
206-
var gcAvg = 0;
207-
var garbageAvg = 0;
208-
var retainedAvg = 0;
209-
times.forEach(function(x) { timesAvg += x; });
210-
gcTimes.forEach(function(x) { gcAvg += x; });
211-
garbageTimes.forEach(function(x) { garbageAvg += x; });
212-
retainedTimes.forEach(function(x) { retainedAvg += x; });
195+
bp.getAverages = function (times, gcTimes, garbageTimes, retainedTimes) {
213196
return {
214-
gcTime: gcAvg / gcTimes.length,
215-
time: timesAvg / times.length,
216-
garbage: garbageAvg / garbageTimes.length,
217-
retained: retainedAvg / retainedTimes.length
197+
gcTime: bp.Statistics.getMean(gcTimes),
198+
time: bp.Statistics.getMean(times),
199+
garbage: bp.Statistics.getMean(garbageTimes),
200+
retained: bp.Statistics.getMean(retainedTimes)
218201
};
219202
};
220203

@@ -269,8 +252,7 @@ bp.calcStats = function() {
269252
tpa = bp.getTimesPerAction(stepName),
270253
reportModel,
271254
avg,
272-
timesConfidenceInterval,
273-
timesConfidenceRange;
255+
timesConfidenceInterval;
274256

275257
bp.updateTimes(tpa, tpa.nextEntry, 'gcTimes', gcTimeForStep);
276258
bp.updateTimes(tpa, tpa.nextEntry, 'garbageTimes', garbageTimeForStep / 1e3);
@@ -279,27 +261,22 @@ bp.calcStats = function() {
279261

280262
tpa.nextEntry++;
281263
tpa.nextEntry %= bp.runState.numSamples;
282-
avg = bp.getAverage(
264+
avg = bp.getAverages(
283265
tpa.times,
284266
tpa.gcTimes,
285267
tpa.garbageTimes,
286268
tpa.retainedTimes);
287269

288270
timesConfidenceInterval = bp.Statistics.calculateConfidenceInterval(
289-
bp.Statistics.calculateStandardDeviation(tpa.times),
271+
bp.Statistics.calculateStandardDeviation(tpa.times, avg.time),
290272
tpa.times.length
291273
);
292-
timesConfidenceRange = bp.Statistics.getConfidenceRange(
293-
avg.time,
294-
timesConfidenceInterval
295-
);
274+
296275
reportModel = bp.generateReportModel({
297276
name: stepName,
298277
avg: avg,
299278
times: tpa.fmtTimes,
300-
timesConfidenceInterval: timesConfidenceInterval,
301-
timesConfidenceRange: timesConfidenceRange,
302-
timesStability: bp.Statistics.getStabilityOfSample(tpa.times, timesConfidenceRange) * 100,
279+
timesRelativeMarginOfError: bp.Statistics.calculateRelativeMarginOfError(timesConfidenceInterval, avg.time),
303280
gcTimes: tpa.fmtGcTimes,
304281
garbageTimes: tpa.fmtGarbageTimes,
305282
retainedTimes: tpa.fmtRetainedTimes

benchmark/web/bp.spec.js

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,28 @@ describe('bp', function() {
3737
describe('.Statistics', function() {
3838
describe('.calculateConfidenceInterval()', function() {
3939
it('should provide the correct confidence interval', function() {
40-
expect(bp.Statistics.calculateConfidenceInterval(30, 1000)).toBe(1.86);
40+
expect(bp.Statistics.calculateConfidenceInterval(30, 1000)).toBe(1.859419264179007);
4141
});
4242
});
4343

4444

45-
describe('.calculateStandardDeviation()', function() {
46-
it('should provide the correct standardDeviation for the provided sample', function() {
47-
expect(bp.Statistics.calculateStandardDeviation([
48-
2,4,4,4,5,5,7,9
49-
])).toBe(2);
50-
});
45+
describe('.calculateRelativeMarginOfError()', function() {
46+
expect(bp.Statistics.calculateRelativeMarginOfError(1.85, 5)).toBe(0.37);
5147
});
5248

5349

54-
describe('.getConfidenceRange()', function() {
55-
it('should return an array of low and high confidence range', function() {
56-
expect(bp.Statistics.getConfidenceRange(100, 1.5)).toEqual([98.5,101.5]);
50+
describe('.getMean()', function() {
51+
it('should return the mean for a given sample', function() {
52+
expect(bp.Statistics.getMean([1,2,5,4])).toBe(3);
5753
});
58-
59-
60-
it('should round values to 2 decimal points', function() {
61-
expect(bp.Statistics.getConfidenceRange(100,1.111111)).toEqual([100-1.11,100+1.11]);
62-
})
6354
});
6455

6556

66-
describe('.getStabilityOfSample()', function() {
67-
it('should return the percentage of samples that fall within the provided range', function() {
68-
expect(bp.Statistics.getStabilityOfSample([0,5,5,10],[5,6])).toBe(0.5);
57+
describe('.calculateStandardDeviation()', function() {
58+
it('should provide the correct standardDeviation for the provided sample and mean', function() {
59+
expect(bp.Statistics.calculateStandardDeviation([
60+
2,4,4,4,5,5,7,9
61+
], 5)).toBe(2);
6962
});
7063
});
7164
});
@@ -396,9 +389,9 @@ describe('bp', function() {
396389
});
397390

398391

399-
describe('.getAverage()', function() {
392+
describe('.getAverages()', function() {
400393
it('should return the average of a set of numbers', function() {
401-
expect(bp.getAverage([100,0,50,75,25], [2,4,2,4,3], [1,2],[3,4])).toEqual({
394+
expect(bp.getAverages([100,0,50,75,25], [2,4,2,4,3], [1,2],[3,4])).toEqual({
402395
gcTime: 3,
403396
time: 50,
404397
garbage: 1.5,
@@ -450,8 +443,8 @@ describe('bp', function() {
450443
});
451444

452445

453-
it('should call getAverage() with the correct info', function() {
454-
var spy = spyOn(bp, 'getAverage').andCallThrough();
446+
it('should call getAverages() with the correct info', function() {
447+
var spy = spyOn(bp, 'getAverages').andCallThrough();
455448
bp.calcStats();
456449
expect(spy).toHaveBeenCalledWith([ 3, 7, 5 ], [ 1, 3, 2 ], [50,50,0.2], [25,25,0.1]);
457450
});
@@ -485,7 +478,8 @@ describe('bp', function() {
485478
times: ['1','2'],
486479
gcTimes: ['4','5'],
487480
garbageTimes: ['6','7'],
488-
retainedTimes: ['7','8']
481+
retainedTimes: ['7','8'],
482+
timesConfidenceInterval: 0.5555
489483
})).toEqual({
490484
name : 'Some Step',
491485
avg : {
@@ -498,7 +492,8 @@ describe('bp', function() {
498492
times : '1<br>2',
499493
gcTimes : '4<br>5',
500494
garbageTimes : '6<br>7',
501-
retainedTimes : '7<br>8'
495+
retainedTimes : '7<br>8',
496+
timesConfidenceInterval: '0.56'
502497
});
503498
});
504499
});

benchmark/web/tree.html

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,7 @@
6868
<tr class="sampleContainer">
6969
<td><%= name %></td>
7070
<td class="average">
71-
test:<%= avg.time %>ms
72-
<br>
73-
times within range: <%= timesStability %>%
74-
<br>
75-
confidence interval: <%= timesConfidenceInterval %>
76-
<br>
77-
confidence range:
78-
<%= timesConfidenceRange[0] %> -
79-
<%= timesConfidenceRange[1] %>
71+
test:<%= avg.time %>ms &plusmn; <%- Math.round(timesRelativeMarginOfError * 100) %>%
8072
<br>
8173
gc:<%= avg.gcTime %>ms
8274
<br>

0 commit comments

Comments
 (0)