diff --git a/benchmark/web/bp.js b/benchmark/web/bp.js
index fc98e578a..9d7af676d 100644
--- a/benchmark/web/bp.js
+++ b/benchmark/web/bp.js
@@ -3,6 +3,7 @@ bp.steps = window.benchmarkSteps = [];
bp.runState = {
numSamples: 10,
recentTimePerStep: {},
+ recentGCTimePerStep: {},
timesPerAction: {}
};
@@ -82,13 +83,25 @@ bp.runTimedTest = function (bs) {
}
var startTime = bp.numMilliseconds();
bs.fn();
- return bp.numMilliseconds() - startTime;
+ var endTime = bp.numMilliseconds() - startTime;
+
+ var startGCTime = bp.numMilliseconds();
+ if (typeof window.gc === 'function') {
+ window.gc();
+ }
+ var endGCTime = bp.numMilliseconds() - startGCTime;
+ return {
+ time: endTime,
+ gcTime: endGCTime
+ };
};
bp.runAllTests = function (done) {
if (bp.runState.iterations--) {
bp.steps.forEach(function(bs) {
- bp.runState.recentTimePerStep[bs.name] = bp.runTimedTest(bs);
+ var testResults = bp.runTimedTest(bs);
+ bp.runState.recentTimePerStep[bs.name] = testResults.time;
+ bp.runState.recentGCTimePerStep[bs.name] = testResults.gcTime;
});
bp.report = bp.calcStats();
bp.writeReport(bp.report);
@@ -103,20 +116,28 @@ bp.runAllTests = function (done) {
}
}
-bp.generateReportPartial = function(name, avg, times) {
+bp.generateReportPartial = function(name, avg, fmtTimes, gcTimes) {
return bp.interpolateHtml(
- '
%0 | %1ms | [%2]ms |
',
+ '%0 | test:%1ms gc:%2ms combined: %3ms | %4 | %5 |
',
[
name,
- ('' + avg).substr(0,6),
- times.join(', ')
+ ('' + avg.time).substr(0,6),
+ ('' + avg.gcTime).substr(0,6),
+ ('' + (avg.time + avg.gcTime)).substr(0,6),
+ fmtTimes.join('
'),
+ gcTimes.join('
')
]);
};
-bp.getAverage = function (times, runState) {
- var avg = 0;
- times.forEach(function(x) { avg += x; });
- return avg / times.length;
+bp.getAverage = function (times, gcTimes, runState) {
+ var timesAvg = 0;
+ var gcAvg = 0;
+ times.forEach(function(x) { timesAvg += x; });
+ gcTimes.forEach(function(x) { gcAvg += x; });
+ return {
+ gcTime: gcAvg / gcTimes.length,
+ time: timesAvg / times.length
+ };
};
bp.writeReport = function(reportContent) {
@@ -129,6 +150,8 @@ bp.getTimesPerAction = function(name) {
tpa = bp.runState.timesPerAction[name] = {
times: [], // circular buffer
fmtTimes: [],
+ fmtGCTimes: [],
+ gcTimes: [],
nextEntry: 0
}
}
@@ -149,17 +172,25 @@ bp.calcStats = function() {
bp.steps.forEach(function(bs) {
var stepName = bs.name,
timeForStep = bp.runState.recentTimePerStep[stepName],
+ gcTimeForStep = bp.runState.recentGCTimePerStep[stepName],
tpa = bp.getTimesPerAction(stepName),
avg;
- tpa.fmtTimes[tpa.nextEntry] = ('' + timeForStep).substr(0,6);
+ tpa.fmtTimes[tpa.nextEntry] = timeForStep.toString().substr(0, 6);
tpa.fmtTimes = bp.rightSizeTimes(tpa.fmtTimes);
+
+ tpa.fmtGCTimes[tpa.nextEntry] = gcTimeForStep.toString().substr(0, 6);
+ tpa.fmtGCTimes = bp.rightSizeTimes(tpa.fmtGCTimes);
+
+ tpa.gcTimes[tpa.nextEntry] = gcTimeForStep;
+ tpa.gcTimes = bp.rightSizeTimes(tpa.gcTimes);
+
tpa.times[tpa.nextEntry++] = timeForStep;
tpa.times = bp.rightSizeTimes(tpa.times);
- tpa.nextEntry %= bp.runState.numSamples;
- avg = bp.getAverage(tpa.times, bp.runState);
- report += bp.generateReportPartial(stepName, avg, tpa.fmtTimes);
+ tpa.nextEntry %= bp.runState.numSamples;
+ avg = bp.getAverage(tpa.times, tpa.gcTimes);
+ report += bp.generateReportPartial(stepName, avg, tpa.fmtTimes, tpa.fmtGCTimes);
});
return report;
};
diff --git a/benchmark/web/bp.spec.js b/benchmark/web/bp.spec.js
index 69ca4043c..cd45f1de0 100644
--- a/benchmark/web/bp.spec.js
+++ b/benchmark/web/bp.spec.js
@@ -27,6 +27,7 @@ describe('bp', function() {
bp.runState = {
numSamples: 10,
recentTimePerStep: {},
+ recentGCTimePerStep: {},
timesPerAction: {}
};
});
@@ -283,7 +284,7 @@ describe('bp', function() {
it('should return the time required to run the test', function() {
var times = {};
- expect(typeof bp.runTimedTest(mockStep, times)).toBe('number');
+ expect(typeof bp.runTimedTest(mockStep, times).time).toBe('number');
});
});
@@ -358,7 +359,10 @@ describe('bp', function() {
describe('.getAverage()', function() {
it('should return the average of a set of numbers', function() {
- expect(bp.getAverage([100,0,50,75,25])).toBe(50);
+ expect(bp.getAverage([100,0,50,75,25], [2,4,2,4,3])).toEqual({
+ gcTime: 3,
+ time: 50
+ });
});
});
@@ -372,27 +376,37 @@ describe('bp', function() {
recentTimePerStep: {
fakeStep: 5
},
+ recentGCTimePerStep: {
+ fakeStep: 2
+ },
timesPerAction: {
fakeStep: {
times: [3,7],
fmtTimes: ['3', '7'],
+ fmtGCTimes: ['1','3'],
+ gcTimes: [1,3],
nextEntry: 2
},
}
};
});
+
it('should call generateReportPartial() with the correct info', function() {
var spy = spyOn(bp, 'generateReportPartial');
bp.calcStats();
- expect(spy).toHaveBeenCalledWith('fakeStep', 5, ['3','7','5']);
+ expect(spy).toHaveBeenCalledWith('fakeStep', {time: 5, gcTime: 2}, ['3','7','5'], ['1','3','2'])
+ expect(spy.calls[0].args[0]).toBe('fakeStep');
+ expect(spy.calls[0].args[1].gcTime).toBe(2);
+ expect(spy.calls[0].args[1].time).toBe(5);
+ expect(spy.calls[0].args[2]).toEqual(['3','7', '5']);
});
it('should call getAverage() with the correct info', function() {
- var spy = spyOn(bp, 'getAverage');
+ var spy = spyOn(bp, 'getAverage').andCallThrough();
bp.calcStats();
- expect(spy).toHaveBeenCalledWith([3,7,5], bp.runState);
+ expect(spy).toHaveBeenCalledWith([ 3, 7, 5 ], [ 1, 3, 2 ]);
});
@@ -414,8 +428,8 @@ describe('bp', function() {
describe('.generateReportPartial()', function() {
it('should return an html string with provided values', function() {
bp.runState.numSamples = 9;
- expect(bp.generateReportPartial('foo', 10, [9,11])).
- toBe('foo | 10ms | [9, 11]ms |
')
+ expect(bp.generateReportPartial('foo', {time: 10, gcTime: 5}, ['9', '11'], ['4','6'])).
+ toBe('foo | test:10ms gc:5ms combined: 15ms | 9 11 | 4 6 |
')
});
});
diff --git a/benchmark/web/tree.html b/benchmark/web/tree.html
index 26e701b68..391a780a5 100644
--- a/benchmark/web/tree.html
+++ b/benchmark/web/tree.html
@@ -43,7 +43,8 @@
step |
average |
- samples |
+ test time (ms) |
+ gc time (ms) |