184 lines
4.4 KiB
JavaScript
184 lines
4.4 KiB
JavaScript
/*
|
|
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
|
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
|
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
|
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
|
* Code distributed by Google as part of the polymer project is also
|
|
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
|
*/
|
|
|
|
(function(global) {
|
|
'use strict';
|
|
|
|
function now() {
|
|
return global.performance && typeof performance.now == 'function' ?
|
|
performance.now() : Date.now();
|
|
}
|
|
|
|
function checkpoint() {
|
|
if (global.Platform &&
|
|
typeof Platform.performMicrotaskCheckpoint == 'function') {
|
|
Platform.performMicrotaskCheckpoint();
|
|
}
|
|
}
|
|
|
|
// TODO(rafaelw): Add simple Promise polyfill for IE.
|
|
|
|
var TESTING_TICKS = 400;
|
|
var TICKS_PER_FRAME = 16;
|
|
var MAX_RUNS = 50;
|
|
|
|
function Benchmark(testingTicks, ticksPerFrame, maxRuns) {
|
|
this.testingTicks = testingTicks || TESTING_TICKS;
|
|
this.ticksPerFrame = ticksPerFrame || TICKS_PER_FRAME;
|
|
this.maxRuns = maxRuns || 50;
|
|
this.average = 0;
|
|
}
|
|
|
|
Benchmark.prototype = {
|
|
// Abstract API
|
|
setup: function(variation) {},
|
|
test: function() {
|
|
throw Error('Not test function found');
|
|
},
|
|
cleanup: function() {},
|
|
|
|
runOne: function(variation) {
|
|
this.setup(variation);
|
|
|
|
var before = now();
|
|
this.test(variation);
|
|
|
|
var self = this;
|
|
|
|
return Promise.resolve().then(function() {
|
|
checkpoint();
|
|
|
|
var after = now();
|
|
|
|
self.cleanup(variation);
|
|
return after - before;
|
|
});
|
|
},
|
|
|
|
runMany: function(count, variation) {
|
|
var self = this;
|
|
|
|
return new Promise(function(fulfill) {
|
|
var total = 0;
|
|
|
|
function next(time) {
|
|
if (!count) {
|
|
fulfill(total);
|
|
return;
|
|
}
|
|
|
|
self.runOne(variation).then(function(time) {
|
|
count--;
|
|
total += time;
|
|
next();
|
|
});
|
|
}
|
|
|
|
requestAnimationFrame(next);
|
|
});
|
|
},
|
|
|
|
runVariation: function(variation, reportFn) {
|
|
var self = this;
|
|
reportFn = reportFn || function() {}
|
|
|
|
return new Promise(function(fulfill) {
|
|
self.runMany(3, variation).then(function(time) {
|
|
return time/3;
|
|
}).then(function(estimate) {
|
|
var runsPerFrame = Math.ceil(self.ticksPerFrame / estimate);
|
|
var frames = Math.ceil(self.testingTicks / self.ticksPerFrame);
|
|
var maxFrames = Math.ceil(self.maxRuns / runsPerFrame);
|
|
|
|
frames = Math.min(frames, maxFrames);
|
|
var count = 0;
|
|
var total = 0;
|
|
|
|
function next() {
|
|
if (!frames) {
|
|
self.average = total / count;
|
|
self.dispose();
|
|
fulfill(self.average);
|
|
return;
|
|
}
|
|
|
|
self.runMany(runsPerFrame, variation).then(function(time) {
|
|
frames--;
|
|
total += time;
|
|
count += runsPerFrame;
|
|
reportFn(variation, count);
|
|
next();
|
|
});
|
|
}
|
|
|
|
next();
|
|
});
|
|
});
|
|
},
|
|
|
|
run: function(variations, reportFn) {
|
|
if (!Array.isArray(variations)) {
|
|
return this.runVariation(variations, reportFn);
|
|
}
|
|
|
|
var self = this;
|
|
variations = variations.slice();
|
|
return new Promise(function(fulfill) {
|
|
var results = [];
|
|
|
|
function next() {
|
|
if (!variations.length) {
|
|
fulfill(results);
|
|
return;
|
|
}
|
|
|
|
var variation = variations.shift();
|
|
self.runVariation(variation, reportFn).then(function(time) {
|
|
results.push(time);
|
|
next();
|
|
});
|
|
}
|
|
|
|
next();
|
|
});
|
|
}
|
|
};
|
|
|
|
function all(benchmarks, variations, statusFn) {
|
|
return new Promise(function(fulfill) {
|
|
var results = [];
|
|
var current;
|
|
|
|
function next() {
|
|
current = benchmarks.shift();
|
|
|
|
if (!current) {
|
|
fulfill(results);
|
|
return;
|
|
}
|
|
|
|
function update(variation, runs) {
|
|
statusFn(current, variation, runs);
|
|
}
|
|
|
|
current.run(variations, update).then(function(time) {
|
|
results.push(time);
|
|
next();
|
|
});
|
|
}
|
|
|
|
next();
|
|
});
|
|
}
|
|
|
|
global.Benchmark = Benchmark;
|
|
global.Benchmark.all = all;
|
|
|
|
})(this);
|