Comparing version 0.1.338 to 0.1.339
789
benchmark.js
/*! | ||
* Benchmark.js | ||
* Copyright Mathias Bynens <http://mths.be/> | ||
* Copyright 2010-2011 Mathias Bynens <http://mths.be/> | ||
* Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/> | ||
@@ -25,2 +25,5 @@ * Modified by John-David Dalton <http://allyoucanleet.com/> | ||
/** Used to control expiration of persisted data */ | ||
STORE_KEY_REV = 3, | ||
/** Unit of the timer */ | ||
@@ -39,3 +42,3 @@ TIMER_UNIT = 'ms', | ||
/** | ||
* T-Distribution critical values for 95% confidence | ||
* T-Distribution two-tailed critical values for 95% confidence | ||
* http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm | ||
@@ -79,2 +82,3 @@ */ | ||
* @constructor | ||
* @param {String} name A name to identify the benchmark. | ||
* @param {Function} fn The test to benchmark. | ||
@@ -87,10 +91,10 @@ * @param {Object} [options={}] Options object. | ||
* | ||
* // with options | ||
* var bench = new Benchmark(fn, { | ||
* // or using a name first | ||
* var bench = new Benchmark("foo", fn); | ||
* | ||
* // name used by Benchmark#toString to identify a benchmark. | ||
* "name": "apples", | ||
* // or with options | ||
* var bench = new Benchmark("foo", fn, { | ||
* | ||
* // id, displayed by Benchmark#toString if `name` is not available | ||
* "id": "a1", | ||
* // displayed by Benchmark#toString if `name` is not available | ||
* "id": "xyz", | ||
* | ||
@@ -113,10 +117,22 @@ * // called when the benchmark starts | ||
* // called when benchmark is complete | ||
* "onComplete": onComplete | ||
* "onComplete": onComplete, | ||
* | ||
* // compiled/called before the test loop | ||
* "setup": setup, | ||
* | ||
* // compiled/called after the test loop | ||
* "teardown": teardown | ||
* }); | ||
*/ | ||
function Benchmark(fn, options) { | ||
function Benchmark(name, fn, options) { | ||
// juggle arguments | ||
var me = this; | ||
fn.uid || (fn.uid = ++cache.counter); | ||
if (isClassOf(name, 'Function')) { | ||
options = fn; | ||
fn = name; | ||
} else { | ||
me.name = name; | ||
} | ||
// apply options | ||
options = extend({ }, options); | ||
forIn(options, function(value, key) { | ||
@@ -132,4 +148,6 @@ // add event listeners | ||
me.fn = fn; | ||
fn.uid || (fn.uid = ++cache.counter); | ||
me.created = +new Date; | ||
me.options = options; | ||
me.stats = extend({ }, me.stats); | ||
me.times = extend({ }, me.times); | ||
@@ -174,4 +192,4 @@ } | ||
invoke(Benchmark.CALIBRATIONS, { | ||
'async': async, | ||
'methodName': 'run', | ||
'name': 'run', | ||
'args': async, | ||
'onCycle': onCycle, | ||
@@ -215,5 +233,12 @@ 'onComplete': callback | ||
function clock() { | ||
var args, | ||
fallback, | ||
timerNS, | ||
timerRes, | ||
min = 0.0015, | ||
proto = Benchmark.prototype, | ||
code = '#{setup}var r$,i$=m$.count,f$=m$.fn,#{start};while(i$--){|}#{end};#{teardown}return{time:r$,uid:"$"}|m$.teardown&&m$.teardown();|f$()|m$.setup&&m$.setup();|m$,n$'; | ||
clock = function(me) { | ||
var body, | ||
embedded, | ||
var embedded, | ||
result, | ||
@@ -226,6 +251,8 @@ fn = me.fn, | ||
try { | ||
// extract test body | ||
body = (String(fn).match(/^[^{]+{([\s\S]*)}\s*$/) || 0)[1]; | ||
// compile while-loop using extracted body | ||
embedded = Function(args, code[0] + body + code[1]); | ||
// insert test body into the while-loop | ||
embedded = Function(args, | ||
interpolate(code[0], { 'setup': getSource(me.setup) }) + | ||
getSource(fn) + | ||
interpolate(code[1], { 'teardown': getSource(me.teardown) }) | ||
); | ||
@@ -293,10 +320,2 @@ if (compilable == null) { | ||
var args, | ||
fallback, | ||
timerNS, | ||
timerRes, | ||
min = 0.0015, | ||
proto = Benchmark.prototype, | ||
code = 'var r$,i$=m$.count,f$=m$.fn,#{start};while(i$--){|}#{end};return{time:r$,uid:"$"}|f$()|m$,n$'; | ||
// detect nanosecond support: | ||
@@ -361,2 +380,3 @@ // Java System.nanoTime() | ||
} | ||
// inject uid into variable names to avoid collisions with | ||
@@ -366,3 +386,7 @@ // embedded tests and create non-embedding fallback | ||
args = code.pop(); | ||
fallback = Function(args, code[0] + code.pop() + code[1]); | ||
fallback = Function(args, | ||
interpolate(code[0], { 'setup': code.pop() }) + | ||
code.pop() + | ||
interpolate(code[1], { 'teardown': code.pop() }) | ||
); | ||
@@ -375,9 +399,37 @@ // resolve time to achieve a percent uncertainty of 1% | ||
/** | ||
* Gets the critical value for the specified degrees of freedom. | ||
* @private | ||
* @param {Number} df The degrees of freedom. | ||
* @returns {Number} The critical value. | ||
*/ | ||
function getCriticalValue(df) { | ||
return T_DISTRIBUTION[df] || T_DISTRIBUTION.Infinity; | ||
} | ||
/** | ||
* Gets the source code of a function. | ||
* @private | ||
* @param {Function} fn The function. | ||
* @returns {String} The function's source code. | ||
*/ | ||
function getSource(fn) { | ||
return trim((/^[^{]+{([\s\S]*)}\s*$/.exec(fn) || 0)[1] || '') | ||
.replace(/([^\n])$/, '$1\n'); | ||
} | ||
/** | ||
* Gets the storage key of the benchmark. | ||
* @private | ||
* @param {Object} me The benchmark instance. | ||
* @param {Object} me The benchmark instance OR options object. | ||
* @returns {String} The storage key. | ||
*/ | ||
function getStoreKey(me) { | ||
return ['benchmark.js', 'r1', TIMER_UNIT, me.fn.uid, Benchmark.platform].join(':'); | ||
var options = extend({ | ||
'rev': STORE_KEY_REV, | ||
'unit': TIMER_UNIT, | ||
'uid': me.fn && me.fn.uid, | ||
'platform': Benchmark.platform | ||
}, me.constructor == Object && me); | ||
return ['benchmark.js', 'r' + options.rev, options.unit, options.uid, options.platform].join(':'); | ||
} | ||
@@ -391,13 +443,21 @@ | ||
function store(me) { | ||
var objects = [me], | ||
result = []; | ||
function record(value, key) { | ||
// record properties with numeric values | ||
if (isClassOf(value, 'Number') && | ||
/^(?:MoE|RME|SD|SEM|[^A-Z]+)$/.test(key)) { | ||
result.push(key + ':' + value); | ||
} | ||
else if (value && isClassOf(value, 'Object')) { | ||
objects.push(value); | ||
} | ||
} | ||
if (HAS_STORAGE) { | ||
localStorage[getStoreKey(me)] = | ||
join(reduce([me, me.times], function(record, object) { | ||
forIn(object, function(value, key) { | ||
// record properties with numeric values | ||
if (isClassOf(value, 'Number') && /^(?:MoE|RME|SD|SEM|[^A-Z]+)$/.test(key)) { | ||
record[key] = value; | ||
} | ||
}); | ||
return record; | ||
}, { })); | ||
while (objects.length) { | ||
forIn(objects.pop(), record); | ||
} | ||
localStorage[getStoreKey(me)] = result.join(); | ||
} | ||
@@ -414,17 +474,33 @@ } | ||
var data, | ||
key = getStoreKey(me), | ||
key, | ||
match, | ||
object, | ||
value, | ||
objects = [me], | ||
persist = me.persist, | ||
expires = isClassOf(persist, 'Number') ? persist * 864e5 : Infinity; | ||
// load and ensure data hasn't expired | ||
if (HAS_STORAGE) { | ||
// load data and ensure it hasn't expired | ||
data = (data = localStorage[key]) && | ||
+new Date - (/created: (\d+)/.exec(data) || 0)[1] < expires && data; | ||
// copy persisted values to benchmark | ||
each(data && data.split(',') || [], function(pair) { | ||
pair = pair.split(': '); | ||
(/^(?:cycle|elapsed|period|start|stop)$/.test(pair[0]) ? me.times : me)[pair[0]] = +pair[1]; | ||
}); | ||
data = (data = localStorage[getStoreKey(me)]) && | ||
+new Date - (/created:(\d+)/.exec(data) || 0)[1] < expires && data; | ||
} | ||
// restore values | ||
if (data) { | ||
while (objects.length) { | ||
object = objects.pop(); | ||
for (key in object) { | ||
value = object[key]; | ||
match = RegExp(key + ':([^,]+)').exec(data); | ||
// extract value and remove from data | ||
if (match) { | ||
data = data.replace(match[0], ''); | ||
object[key] = +match[1]; | ||
} | ||
else if (value && isClassOf(value, 'Object')) { | ||
objects.push(value); | ||
} | ||
} | ||
} | ||
} | ||
return !!data; | ||
@@ -441,9 +517,14 @@ } | ||
function clearStorage() { | ||
if (HAS_STORAGE) { | ||
forIn(localStorage, function(value, key, object) { | ||
if (!key.indexOf('benchmark.js:')) { | ||
object.removeItem(key); | ||
// use brute force because Firefox errors attempting for-in on localStorage | ||
each(HAS_STORAGE ? ['ns', 'us', 'ms'] : [], function(unit) { | ||
var uid, | ||
rev = 0; | ||
while (++rev <= STORE_KEY_REV) { | ||
uid = -3; | ||
while (++uid < 100) { | ||
localStorage.removeItem(getStoreKey({ 'rev': rev, 'unit': unit, 'uid': uid })); | ||
} | ||
}); | ||
} | ||
} | ||
}); | ||
} | ||
@@ -458,2 +539,3 @@ | ||
* @param {Function} callback The function called per iteration. | ||
* @returns {Array} The array iterated over. | ||
*/ | ||
@@ -469,6 +551,7 @@ function each(array, callback) { | ||
} | ||
return array; | ||
} | ||
/** | ||
* Copies source properties to the destination object. | ||
* Copies own/inherited properties of a source object to the destination object. | ||
* @static | ||
@@ -481,5 +564,6 @@ * @member Benchmark | ||
function extend(destination, source) { | ||
forIn(source || { }, function(value, key) { | ||
destination[key] = value; | ||
}); | ||
source || (source = { }); | ||
for (var key in source) { | ||
destination[key] = source[key]; | ||
} | ||
return destination; | ||
@@ -493,6 +577,36 @@ } | ||
* @param {Array} array The array to iterate over. | ||
* @param {Function} callback The function called per iteration. | ||
* @param {Function|String} callback The function/alias called per iteration. | ||
* @returns {Array} A new array of values that passed callback filter. | ||
* @example | ||
* | ||
* // get odd numbers | ||
* Benchmark.filter([1, 2, 3, 4, 5], function(n) { | ||
* return n % 2; | ||
* }); // -> [1, 3, 5]; | ||
* | ||
* // get fastest benchmarks | ||
* Benchmark.filter(benches, "fastest"); | ||
* | ||
* // get slowest benchmarks | ||
* Benchmark.filter(benches, "slowest"); | ||
* | ||
* // get benchmarks that completed without erroring | ||
* Benchmark.filter(benches, "successful"); | ||
*/ | ||
function filter(array, callback) { | ||
var source; | ||
if (callback == 'successful') { | ||
// callback to exclude errored or unrun benchmarks | ||
callback = function(bench) { return bench.cycles; }; | ||
} | ||
else if (/^(?:fast|slow)est$/.test(callback)) { | ||
// get successful benchmarks | ||
array = filter(array, 'successful'); | ||
// sort descending fastest to slowest | ||
array.sort(function(a, b) { return b.compare(a); }); | ||
// set source benchmark | ||
source = array[callback == 'fastest' ? 0 : array.length - 1]; | ||
// callback to filter fastest/slowest | ||
callback = function(bench) { return !source.compare(bench); }; | ||
} | ||
return reduce(array, function(result, value, index) { | ||
@@ -509,2 +623,3 @@ return callback(value, index, array) ? result.push(value) && result : result; | ||
* @param {Function} callback The function called per iteration. | ||
* @returns {Object} The object iterated over. | ||
*/ | ||
@@ -517,2 +632,3 @@ function forIn(object, callback) { | ||
} | ||
return object; | ||
} | ||
@@ -551,3 +667,3 @@ | ||
object = Object(object); | ||
if (typeof hasOwnProperty == 'function') { | ||
if (isClassOf(hasOwnProperty, 'Function')) { | ||
result = hasOwnProperty.call(object, key); | ||
@@ -573,3 +689,3 @@ } | ||
* @param {Mixed} value The value to search for. | ||
* @returns {Number} The index of the matched value or -1. | ||
* @returns {Number} The index of the matched value or `-1`. | ||
*/ | ||
@@ -592,4 +708,5 @@ function indexOf(array, value) { | ||
* @param {Array} benches Array of benchmarks to iterate over. | ||
* @param {String|Object} methodName Name of method to invoke or options object. | ||
* @param {Mixed} args Arguments to invoke the method with. | ||
* @param {String|Object} name The name of the method to invoke OR options object. | ||
* @param {Mixed} [, arg1, arg2, ...] Arguments to invoke the method with. | ||
* @returns {Array} A new array of values returned from each method invoked. | ||
* @example | ||
@@ -601,3 +718,3 @@ * | ||
* // invoke `emit` with arguments | ||
* Benchmark.invoke(benches, "emit", ["complete", b, c]); | ||
* Benchmark.invoke(benches, "emit", "complete", listener); | ||
* | ||
@@ -608,3 +725,3 @@ * // invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks | ||
* // invoke the `run` method | ||
* "methodName": "run", | ||
* "name": "run", | ||
* | ||
@@ -617,2 +734,5 @@ * // pass a single argument | ||
* | ||
* // called before any benchmarks have been invoked. | ||
* "onStart": onStart, | ||
* | ||
* // called between invoking benchmarks | ||
@@ -625,49 +745,49 @@ * "onCycle": onCycle, | ||
*/ | ||
function invoke(benches, methodName, args) { | ||
var async, | ||
function invoke(benches, name) { | ||
var args, | ||
async, | ||
bench, | ||
queued, | ||
i = 0, | ||
length = benches.length, | ||
options = { 'onComplete': noop, 'onCycle': noop }; | ||
options = { 'onStart': noop, 'onCycle': noop, 'onComplete': noop }, | ||
result = benches.slice(0); | ||
function onInvoke(me) { | ||
function execute() { | ||
var listeners; | ||
// insert invoke's "complete" listener before others so it's executed first | ||
if (async) { | ||
me.on('complete', onComplete); | ||
listeners = me.events['complete']; | ||
// use "next" as a listener | ||
bench.on('complete', next); | ||
listeners = bench.events['complete']; | ||
listeners.splice(0, 0, listeners.pop()); | ||
} | ||
// execute method | ||
me[methodName].apply(me, args || []); | ||
// if synchronous return next benchmark after completing the current | ||
return !async && onComplete(me); | ||
result[i] = bench[name].apply(bench, args); | ||
// if synchronous return true until finished | ||
return async || next(); | ||
} | ||
function onComplete(me) { | ||
var next; | ||
function next() { | ||
var last = bench; | ||
bench = false; | ||
// remove invoke's "complete" listener and call the rest | ||
if (async) { | ||
me.removeListener('complete', onComplete); | ||
me.emit('complete'); | ||
last.removeListener('complete', next); | ||
last.emit('complete'); | ||
} | ||
// choose next benchmark if not exiting early | ||
if (options.onCycle(me) !== false) { | ||
if (options.onCycle.call(benches, last) !== false) { | ||
if (queued) { | ||
next = benches.shift(); | ||
} else if (++i < length) { | ||
next = benches[i]; | ||
bench = benches.shift(); | ||
} else { | ||
bench = benches[++i]; | ||
} | ||
} | ||
if (next) { | ||
if (bench) { | ||
if (async) { | ||
call(next, onInvoke, async); | ||
call(bench, execute, async); | ||
} else { | ||
return next; | ||
return true; | ||
} | ||
} else { | ||
options.onComplete(me); | ||
options.onComplete.call(benches, last); | ||
} | ||
@@ -680,30 +800,27 @@ // when async the `return false` will cancel the rest of the "complete" | ||
if (typeof methodName == 'string') { | ||
args = isArray(args || (args = [])) ? args : [args]; | ||
} | ||
else { | ||
// juggle arguments | ||
options = extend(options, methodName); | ||
methodName = options.methodName; | ||
args = isArray(args = options.args || []) ? args : [args]; | ||
// juggle arguments | ||
if (isClassOf(name, 'String')) { | ||
args = slice.call(arguments, 2); | ||
} else { | ||
options = extend(options, name); | ||
name = options.name; | ||
args = isArray(args = 'args' in options ? options.args : []) ? args : [args]; | ||
queued = options.queued; | ||
// for use with Benchmark#run only | ||
if ('async' in options) { | ||
async = options.async; | ||
} else if (isClassOf(args[0], 'Boolean')) { | ||
async = args[0]; | ||
} | ||
async = (async == null ? Benchmark.prototype.DEFAULT_ASYNC : | ||
async) && HAS_TIMEOUT_API; | ||
} | ||
// async for use with Benchmark#run only | ||
if (name == 'run') { | ||
async = (args[0] == null ? Benchmark.prototype.DEFAULT_ASYNC : | ||
args[0]) && HAS_TIMEOUT_API; | ||
} | ||
// start iterating over the array | ||
if (bench = queued ? benches.shift() : benches[0]) { | ||
options.onStart.call(benches, bench); | ||
if (async) { | ||
onInvoke(bench); | ||
call(bench, execute, async); | ||
} else { | ||
while (bench = onInvoke(bench)); | ||
result.length = 0; | ||
while (execute()); | ||
} | ||
} | ||
return result; | ||
} | ||
@@ -751,4 +868,6 @@ | ||
function isCalibrated() { | ||
return !filter(Benchmark.CALIBRATIONS, | ||
function(cal) { return !cal.cycles; }).length; | ||
return !filter(Benchmark.CALIBRATIONS, function(cal) { | ||
cal.persist && restore(cal); | ||
return !cal.cycles; | ||
}).length; | ||
} | ||
@@ -882,3 +1001,3 @@ | ||
var me = this, | ||
args = [me].concat(slice.call(arguments, 1)), | ||
args = slice.call(arguments, 1), | ||
events = me.events, | ||
@@ -936,2 +1055,3 @@ listeners = events && events[type] || [], | ||
* @member Benchmark | ||
* @returns {Object} The benchmark instance. | ||
*/ | ||
@@ -955,2 +1075,3 @@ function abort() { | ||
} | ||
return me; | ||
} | ||
@@ -990,6 +1111,16 @@ | ||
function compare(other) { | ||
var me = this, | ||
a = { 'lower': me.hz - me.MoE, 'upper': me.hz + me.MoE }, | ||
b = { 'lower': other.hz - other.MoE, 'upper': other.hz + other.MoE }; | ||
return a.lower <= b.upper && a.upper >= b.lower ? 0 : a.lower > b.lower ? 1 : -1; | ||
// use welch t-test | ||
// http://frank.mtsu.edu/~dkfuller/notes302/welcht.pdf | ||
// http://www.public.iastate.edu/~alicia/stat328/Regression%20inference-part2.pdf | ||
var a = this.stats, | ||
b = other.stats, | ||
pow = Math.pow, | ||
bitA = a.variance / a.size, | ||
bitB = b.variance / b.size, | ||
df = pow(bitA + bitB, 2) / ((pow(bitA, 2) / a.size - 1) + (pow(bitB, 2) / b.size - 1)), | ||
t = (a.mean - b.mean) / Math.sqrt(bitA + bitB), | ||
c = getCriticalValue(Math.round(df)); | ||
// check if t-statistic is significant | ||
return Math.abs(t) > c ? (t > 0 ? 1 : -1) : 0; | ||
} | ||
@@ -1000,30 +1131,34 @@ | ||
* @member Benchmark | ||
* @returns {Object} The benchmark instance. | ||
*/ | ||
function reset() { | ||
var changed, | ||
pair, | ||
me = this, | ||
keys = 'MoE RME SD SEM aborted count cycles error hz running'.split(' '), | ||
timeKeys = 'cycle elapsed period start stop'.split(' '), | ||
times = me.times, | ||
proto = me.constructor.prototype; | ||
source = extend(extend({ }, me.constructor.prototype), me.options), | ||
pairs = [[source, me]]; | ||
function check(value, key) { | ||
var other = pair[1][key]; | ||
if (value && isClassOf(value, 'Object')) { | ||
pairs.push([value, other]); | ||
} | ||
else if (!isClassOf(value, 'Function') && | ||
key != 'created' && value != other) { | ||
pair[1][key] = value; | ||
changed = true; | ||
} | ||
} | ||
if (me.running) { | ||
// no worries, reset() is called within abort() | ||
me.abort(); | ||
me.aborted = proto.aborted; | ||
me.aborted = source.aborted; | ||
} | ||
else { | ||
// check if properties have changed and reset them | ||
each(keys, function(key) { | ||
if (me[key] != proto[key]) { | ||
changed = true; | ||
me[key] = proto[key]; | ||
} | ||
}); | ||
each(timeKeys, function(key) { | ||
if (times[key] != proto.times[key]) { | ||
changed = true; | ||
times[key] = proto.times[key]; | ||
} | ||
}); | ||
while (pairs.length) { | ||
pair = pairs.pop(); | ||
(isArray(pair[0]) ? each : forIn)(pair[0], check); | ||
} | ||
if (changed) { | ||
@@ -1033,2 +1168,3 @@ me.emit('reset'); | ||
} | ||
return me; | ||
} | ||
@@ -1052,3 +1188,3 @@ | ||
result += ' ' + x + ' ' + formatNumber(me.hz) + ' ' + pm + | ||
me.RME.toFixed(2) + '% (' + cycles + ' cycle' + (cycles == 1 ? '' : 's') + ')'; | ||
me.stats.RME.toFixed(2) + '% (' + cycles + ' cycle' + (cycles == 1 ? '' : 's') + ')'; | ||
} | ||
@@ -1061,3 +1197,3 @@ return result; | ||
/** | ||
* Performs statistical calculations on benchmark results. | ||
* Computes stats on benchmark results. | ||
* @private | ||
@@ -1074,3 +1210,3 @@ * @param {Object} me The benchmark instance. | ||
queue = [], | ||
burstCount = async ? 2 : 48, | ||
burstCount = async ? 1 : 49, | ||
runCount = me.INIT_RUN_COUNT; | ||
@@ -1080,20 +1216,12 @@ | ||
while (count--) { | ||
sample.push(queue[queue.push(me.clone({ | ||
queue.push(me.clone({ | ||
'computing': true, | ||
'events': { | ||
'complete': [onComplete], | ||
'cycle': [onCycle], | ||
'start': [onStart] | ||
} | ||
})) - 1]); | ||
'events': { 'start': [update], 'cycle': [update] } | ||
})); | ||
} | ||
} | ||
function onComplete(clone) { | ||
// update host run count | ||
me.INIT_RUN_COUNT = clone.INIT_RUN_COUNT; | ||
} | ||
function onCycle(clone) { | ||
// map changes from clone to host | ||
function update() { | ||
// port changes from clone to host | ||
var clone = this; | ||
if (me.running) { | ||
@@ -1105,2 +1233,3 @@ if (clone.cycles) { | ||
me.times.period = clone.times.period; | ||
me.INIT_RUN_COUNT = clone.INIT_RUN_COUNT; | ||
me.emit('cycle'); | ||
@@ -1113,4 +1242,12 @@ } | ||
} | ||
} | ||
else if (me.aborted) { | ||
else { | ||
// reset timer if interrupted by calibrations | ||
if (!calibrating && !calibrated && isCalibrated()) { | ||
calibrated = true; | ||
me.times.start = +new Date; | ||
} | ||
// use hosts last run count | ||
clone.count = me.INIT_RUN_COUNT; | ||
} | ||
} else if (me.aborted) { | ||
clone.abort(); | ||
@@ -1120,16 +1257,4 @@ } | ||
function onStart(clone) { | ||
// reset timer if interrupted by calibrations | ||
if (!calibrating && !calibrated && isCalibrated()) { | ||
calibrated = true; | ||
me.times.start = +new Date; | ||
} | ||
// sync clone's initial run count with host | ||
clone.count = me.INIT_RUN_COUNT; | ||
onCycle(clone); | ||
} | ||
function onInvokeCycle(clone) { | ||
var complete, | ||
mean, | ||
function evaluate(clone) { | ||
var mean, | ||
moe, | ||
@@ -1139,2 +1264,6 @@ rme, | ||
sem, | ||
variance, | ||
index = me.CALIBRATION_INDEX, | ||
cals = me.constructor.CALIBRATIONS || [], | ||
cal = cals[index > 1 ? index : fn.compilable ? 0 : 1], | ||
now = +new Date, | ||
@@ -1144,25 +1273,23 @@ times = me.times, | ||
elapsed = (now - times.start) / 1e3, | ||
maxedOut = burst ? !--burstCount : async && elapsed >= me.MAX_TIME_ELAPSED, | ||
sampleSize = sample.length, | ||
sumOf = function(sum, clone) { return sum + clone.hz; }, | ||
varianceOf = function(sum, clone) { return sum + Math.pow(clone.hz - mean, 2); }; | ||
maxedOut = burst ? !--burstCount : elapsed >= me.MAX_TIME_ELAPSED, | ||
size = sample.push(clone.hz), | ||
sumOf = function(sum, x) { return sum + x; }, | ||
varOf = function(sum, x) { return sum + Math.pow(x - mean, 2); }; | ||
// exit early for unclockable tests | ||
if (clone.hz == Infinity) { | ||
queue.length = sample.length = 0; | ||
// exit early for aborted or unclockable tests | ||
if (aborted || clone.hz == Infinity) { | ||
maxedOut = !(calibrating = size = queue.length = sample.length = 0); | ||
} | ||
// exit early if aborted | ||
if (aborted) { | ||
complete = true; | ||
} | ||
// simulate onComplete and enqueue additional runs if needed | ||
else if (!queue.length) { | ||
if (!queue.length) { | ||
// compute values | ||
mean = reduce(sample, sumOf, 0) / sampleSize || 0; | ||
mean = reduce(sample, sumOf, 0) / size || 0; | ||
// sample variance | ||
variance = reduce(sample, varOf, 0) / (size - 1); | ||
// standard deviation | ||
sd = Math.sqrt(reduce(sample, varianceOf, 0) / (sampleSize - 1)) || 0; | ||
sd = Math.sqrt(variance); | ||
// standard error of the mean | ||
sem = sd / Math.sqrt(sampleSize) || 0; | ||
sem = sd / Math.sqrt(size) || 0; | ||
// margin of error | ||
moe = sem * (T_DISTRIBUTION[sampleSize - 1] || T_DISTRIBUTION.Infinity); | ||
moe = sem * getCriticalValue(size - 1); | ||
// relative margin of error | ||
@@ -1172,71 +1299,87 @@ rme = (moe / mean) * 100 || 0; | ||
// if time permits, or calibrating, increase sample size to reduce the margin of error | ||
if (rme > 1 && (!maxedOut || calibrating)) { | ||
if (maxedOut) { | ||
if (!maxedOut || (calibrating && rme > 1)) { | ||
if (maxedOut && (async || burst)) { | ||
// switch to burst mode | ||
queue.length = 0; | ||
compute(me, !async, true, sample); | ||
} | ||
else { | ||
} else { | ||
enqueue(1); | ||
} | ||
} | ||
// finish up | ||
else { | ||
complete = true; | ||
// set host values | ||
if (!aborted) { | ||
me.running = false; | ||
times.stop = now; | ||
times.elapsed = elapsed; | ||
extend(me.stats, { | ||
'MoE': moe, | ||
'RME': rme, | ||
'SD': sd, | ||
'SEM': sem, | ||
'mean': mean, | ||
'size': size, | ||
'variance': variance | ||
}); | ||
// set statistical data | ||
me.MoE = moe; | ||
me.RME = rme; | ||
me.SD = sd; | ||
me.SEM = sem; | ||
// set host results | ||
me.count = clone.count; | ||
me.running = false; | ||
times.stop = now; | ||
times.elapsed = elapsed; | ||
if (clone.hz != Infinity) { | ||
me.hz = mean; | ||
times.period = 1 / mean; | ||
times.cycle = times.period * me.count; | ||
if (me.hz != Infinity) { | ||
// calibrate by subtracting iteration overhead | ||
if (cal && cal.compare(me) > 0) { | ||
mean = 1 / ((1 / mean) - cal.times.period); | ||
} | ||
me.hz = mean; | ||
times.period = 1 / mean; | ||
times.cycle = times.period * me.count; | ||
} | ||
if (me.persist) { | ||
store(me); | ||
} | ||
} | ||
// record results | ||
if (me.persist) { | ||
store(me); | ||
} | ||
me.INIT_RUN_COUNT = runCount; | ||
me.emit('complete'); | ||
} | ||
} | ||
// cleanup | ||
if (complete) { | ||
queue.length = 0; | ||
me.INIT_RUN_COUNT = runCount; | ||
me.emit('complete'); | ||
} | ||
return !aborted; | ||
} | ||
// init sample and queue | ||
// init sample/queue and begin | ||
sample || (sample = []); | ||
enqueue(sample.length ? 1 : 5); | ||
// run them | ||
invoke(queue, { | ||
'async': async, | ||
'methodName': 'run', | ||
'queued': true, | ||
'onCycle': onInvokeCycle | ||
}); | ||
invoke(queue, { 'name': 'run', 'args': async, 'queued': true, 'onCycle': evaluate }); | ||
} | ||
/** | ||
* Executes each run cycle and computes results. | ||
* @private | ||
* @param {Object} me The benchmark instance. | ||
* Starts running the benchmark. | ||
* @member Benchmark | ||
* @param {Boolean} [async=false] Flag to run asynchronously. | ||
* @returns {Object} The benchmark instance. | ||
*/ | ||
function _run(me, async) { | ||
var clocked; | ||
function run(async) { | ||
var clocked, | ||
me = this; | ||
function onCalibrate(cal) { | ||
function cycle() { | ||
// continue, if not aborted between cycles | ||
if (me.running) { | ||
me.cycles++; | ||
try { | ||
// used by finish() | ||
clocked = clock(me); | ||
} | ||
catch(e) { | ||
me.abort(); | ||
me.error = e; | ||
me.emit('error'); | ||
} | ||
} | ||
// check if calibration is needed | ||
if (me.running) { | ||
if (me.constructor == Calibration || calibrate(me, resume, async)) { | ||
finish(); | ||
} | ||
} else { | ||
finish(); | ||
} | ||
} | ||
function resume(cal) { | ||
if (cal.aborted) { | ||
@@ -1254,6 +1397,3 @@ me.abort(); | ||
fn = me.fn, | ||
index = me.CALIBRATION_INDEX, | ||
times = me.times, | ||
cals = me.constructor.CALIBRATIONS || [], | ||
cal = cals[index > 1 ? index : fn.compilable ? 0 : 1], | ||
count = me.count, | ||
@@ -1263,15 +1403,10 @@ minTime = me.MIN_TIME; | ||
if (me.running) { | ||
// calibrate by subtracting iteration overhead | ||
clocked = times.cycle = Math.max(0, | ||
clocked - ((cal && cal.times.period || 0) * count)); | ||
// time taken to complete last test cycle | ||
times.cycle = clocked; | ||
// seconds per operation | ||
period = times.period = clocked / count; | ||
// ops per second | ||
me.hz = 1 / period; | ||
// do we need to do another cycle? | ||
me.running = clocked < minTime; | ||
// avoid working our way up to this next time | ||
@@ -1300,3 +1435,3 @@ me.INIT_RUN_COUNT = count; | ||
me.count = count; | ||
call(me, _run, async); | ||
call(me, cycle, async); | ||
} else { | ||
@@ -1307,34 +1442,2 @@ me.emit('complete'); | ||
// continue, if not aborted between cycles | ||
if (me.running) { | ||
me.cycles++; | ||
try { | ||
// used by finish() | ||
clocked = clock(me); | ||
} | ||
catch(e) { | ||
me.abort(); | ||
me.error = e; | ||
me.emit('error'); | ||
} | ||
} | ||
// check if calibration is needed | ||
if (me.running) { | ||
if (me.constructor == Calibration || calibrate(me, onCalibrate, async)) { | ||
finish(); | ||
} | ||
} else { | ||
finish(); | ||
} | ||
} | ||
/** | ||
* Starts running the benchmark. | ||
* @member Benchmark | ||
* @param {Boolean} [async=false] Flag to run asynchronously. | ||
*/ | ||
function run(async) { | ||
var me = this; | ||
async = (async == null ? me.DEFAULT_ASYNC : async) && HAS_TIMEOUT_API; | ||
// set running to false so reset() won't call abort() | ||
@@ -1344,2 +1447,3 @@ me.running = false; | ||
me.running = true; | ||
me.count = me.INIT_RUN_COUNT; | ||
@@ -1349,2 +1453,3 @@ me.times.start = +new Date; | ||
async = (async == null ? me.DEFAULT_ASYNC : async) && HAS_TIMEOUT_API; | ||
if (me.persist && restore(me)) { | ||
@@ -1361,6 +1466,7 @@ // use restored data | ||
else if (me.computing) { | ||
_run(me, async); | ||
cycle(); | ||
} else { | ||
compute(me, async); | ||
} | ||
return me; | ||
} | ||
@@ -1537,17 +1643,2 @@ | ||
/** | ||
* Benchmarks to establish iteration overhead. | ||
* @static | ||
* @member Benchmark | ||
* @type Array | ||
*/ | ||
'CALIBRATIONS': (function() { | ||
var a = function() { }, | ||
b = function() { }; | ||
a.uid = -1; | ||
b.uid = -2; | ||
b.compilable = false; | ||
return [new Calibration(a), new Calibration(b)]; | ||
}()), | ||
/** | ||
* The version number. | ||
@@ -1558,3 +1649,3 @@ * @static | ||
*/ | ||
'version': '0.1.338', | ||
'version': '0.1.339', | ||
@@ -1666,3 +1757,3 @@ // clears locally stored data | ||
*/ | ||
'MAX_TIME_ELAPSED': 8, | ||
'MAX_TIME_ELAPSED': 5, | ||
@@ -1677,30 +1768,2 @@ /** | ||
/** | ||
* The margin of error. | ||
* @member Benchmark | ||
* @type Number | ||
*/ | ||
'MoE': 0, | ||
/** | ||
* The relative margin of error (expressed as a percentage of the mean). | ||
* @member Benchmark | ||
* @type Number | ||
*/ | ||
'RME': 0, | ||
/** | ||
* The sample standard deviation. | ||
* @member Benchmark | ||
* @type Number | ||
*/ | ||
'SD': 0, | ||
/** | ||
* The standard error of the mean. | ||
* @member Benchmark | ||
* @type Number | ||
*/ | ||
'SEM': 0, | ||
/** | ||
* The number of times a test was executed. | ||
@@ -1768,2 +1831,59 @@ * @member Benchmark | ||
/** | ||
* An object of stats including mean, margin or error, and standard deviation. | ||
* @member Benchmark | ||
* @type Object | ||
*/ | ||
'stats': { | ||
/** | ||
* The margin of error. | ||
* @member Benchmark#stats | ||
* @type Number | ||
*/ | ||
'MoE': 0, | ||
/** | ||
* The relative margin of error (expressed as a percentage of the mean). | ||
* @member Benchmark#stats | ||
* @type Number | ||
*/ | ||
'RME': 0, | ||
/** | ||
* The sample standard deviation. | ||
* @member Benchmark#stats | ||
* @type Number | ||
*/ | ||
'SD': 0, | ||
/** | ||
* The standard error of the mean. | ||
* @member Benchmark#stats | ||
* @type Number | ||
*/ | ||
'SEM': 0, | ||
/** | ||
* The sample arithmetic mean. | ||
* @member Benchmark#stats | ||
* @type Number | ||
*/ | ||
'mean': 0, | ||
/** | ||
* The sample size. | ||
* @member Benchmark#stats | ||
* @type Number | ||
*/ | ||
'size': 0, | ||
/** | ||
* The sample variance. | ||
* @member Benchmark#stats | ||
* @type Number | ||
*/ | ||
'variance': 0 | ||
}, | ||
/** | ||
* An object of timing data including cycle, elapsed, period, start, and stop. | ||
@@ -1836,3 +1956,9 @@ * @member Benchmark | ||
// run the benchmark | ||
'run': run | ||
'run': run, | ||
// used to perform operations immediately before the test loop | ||
'setup': noop, | ||
// used to perform operations immediately after the test loop | ||
'teardown': noop | ||
}); | ||
@@ -1851,2 +1977,17 @@ | ||
/** | ||
* Benchmarks to establish iteration overhead. | ||
* @static | ||
* @member Benchmark | ||
* @type Array | ||
*/ | ||
Benchmark.CALIBRATIONS = (function() { | ||
var a = function() { }, | ||
b = function() { }; | ||
a.uid = -1; | ||
b.uid = -2; | ||
b.compilable = false; | ||
return [new Calibration(a), new Calibration(b)]; | ||
}()); | ||
/*--------------------------------------------------------------------------*/ | ||
@@ -1853,0 +1994,0 @@ |
@@ -33,6 +33,2 @@ # Benchmark | ||
* [`Benchmark#MIN_TIME`](#MIN_TIME) | ||
* [`Benchmark#MoE`](#MoE) | ||
* [`Benchmark#RME`](#RME) | ||
* [`Benchmark#SD`](#SD) | ||
* [`Benchmark#SEM`](#SEM) | ||
* [`Benchmark#aborted`](#aborted) | ||
@@ -46,2 +42,10 @@ * [`Benchmark#count`](#count) | ||
* [`Benchmark#running`](#running) | ||
* [`Benchmark#stats`](#stats) | ||
* [`Benchmark#stats.MoE`](#MoE) | ||
* [`Benchmark#stats.RME`](#RME) | ||
* [`Benchmark#stats.SD`](#SD) | ||
* [`Benchmark#stats.SEM`](#SEM) | ||
* [`Benchmark#stats.mean`](#mean) | ||
* [`Benchmark#stats.size`](#size) | ||
* [`Benchmark#stats.variance`](#variance) | ||
* [`Benchmark#times`](#times) | ||
@@ -66,19 +70,19 @@ * [`Benchmark#times.cycle`](#cycle) | ||
# Benchmark | ||
## <a name="static-CALIBRATIONS" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1488" title="View in source">Benchmark.CALIBRATIONS</a> | ||
## <a name="static-CALIBRATIONS" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1923" title="View in source">Benchmark.CALIBRATIONS</a> | ||
*(Array)*: Benchmarks to establish iteration overhead. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="static-platform" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1322" title="View in source">Benchmark.platform</a> | ||
## <a name="static-platform" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1428" title="View in source">Benchmark.platform</a> | ||
*(Boolean)*: Platform object containing browser name, version, and operating system. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="static-version" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1503" title="View in source">Benchmark.version</a> | ||
## <a name="static-version" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1594" title="View in source">Benchmark.version</a> | ||
*(String)*: The version number. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="static-clearStorage" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L425" title="View in source">Benchmark.clearStorage()</a> | ||
## <a name="static-clearStorage" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L501" title="View in source">Benchmark.clearStorage()</a> | ||
Removes all benchmark data from local storage. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="static-each" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L443" title="View in source">Benchmark.each(array, callback)</a> | ||
## <a name="static-each" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L525" title="View in source">Benchmark.each(array, callback)</a> | ||
A generic bare-bones `Array#forEach` solution. | ||
@@ -92,4 +96,7 @@ Callbacks may terminate the loop by explicitly returning `false`. | ||
## <a name="static-extend" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L462" title="View in source">Benchmark.extend(destination, source)</a> | ||
Copies source properties to the destination object. | ||
### Returns | ||
*(Array)*: The array iterated over. | ||
## <a name="static-extend" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L545" title="View in source">Benchmark.extend(destination, source)</a> | ||
Copies own/inherited properties of a source object to the destination object. | ||
<sup><code>[▲][1]</code></sup> | ||
@@ -104,3 +111,3 @@ | ||
## <a name="static-filter" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L477" title="View in source">Benchmark.filter(array, callback)</a> | ||
## <a name="static-filter" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L576" title="View in source">Benchmark.filter(array, callback)</a> | ||
A generic bare-bones `Array#filter` solution. | ||
@@ -111,3 +118,3 @@ <sup><code>[▲][1]</code></sup> | ||
1. `array` *(Array)*: The array to iterate over. | ||
2. `callback` *(Function)*: The function called per iteration. | ||
2. `callback` *(Function|String)*: The function/alias called per iteration. | ||
@@ -117,3 +124,18 @@ ### Returns | ||
## <a name="static-forIn" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L490" title="View in source">Benchmark.forIn(object, callback)</a> | ||
### Example | ||
// get odd numbers | ||
Benchmark.filter([1, 2, 3, 4, 5], function(n) { | ||
return n % 2; | ||
}); // -> [1, 3, 5]; | ||
// get fastest benchmarks | ||
Benchmark.filter(benches, "fastest"); | ||
// get slowest benchmarks | ||
Benchmark.filter(benches, "slowest"); | ||
// get benchmarks that completed without erroring | ||
Benchmark.filter(benches, "successful"); | ||
## <a name="static-forIn" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L605" title="View in source">Benchmark.forIn(object, callback)</a> | ||
A generic bare-bones for-in solution for an object's own properties. | ||
@@ -126,3 +148,6 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-formatNumber" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L505" title="View in source">Benchmark.formatNumber(number)</a> | ||
### Returns | ||
*(Object)*: The object iterated over. | ||
## <a name="static-formatNumber" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L621" title="View in source">Benchmark.formatNumber(number)</a> | ||
Converts a number to a more readable comma-separated string representation. | ||
@@ -137,3 +162,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-hasKey" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L523" title="View in source">Benchmark.hasKey(object, key)</a> | ||
## <a name="static-hasKey" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L639" title="View in source">Benchmark.hasKey(object, key)</a> | ||
Checks if an object has the specified key as a direct property. | ||
@@ -149,3 +174,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-indexOf" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L552" title="View in source">Benchmark.indexOf(array, value)</a> | ||
## <a name="static-indexOf" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L668" title="View in source">Benchmark.indexOf(array, value)</a> | ||
A generic bare-bones `Array#indexOf` solution. | ||
@@ -161,3 +186,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-interpolate" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L695" title="View in source">Benchmark.interpolate(string, object)</a> | ||
## <a name="static-interpolate" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L812" title="View in source">Benchmark.interpolate(string, object)</a> | ||
Modify a string by replacing named tokens with matching object property values. | ||
@@ -179,3 +204,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-invoke" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L597" title="View in source">Benchmark.invoke(benches, methodName, args)</a> | ||
## <a name="static-invoke" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L717" title="View in source">Benchmark.invoke(benches, name)</a> | ||
Invokes a given method, with arguments, on all benchmarks in an array. | ||
@@ -186,5 +211,8 @@ <sup><code>[▲][1]</code></sup> | ||
1. `benches` *(Array)*: Array of benchmarks to iterate over. | ||
2. `methodName` *(String|Object)*: Name of method to invoke or options object. | ||
3. `args` *(Mixed)*: Arguments to invoke the method with. | ||
2. `name` *(String|Object)*: The name of the method to invoke OR options object. | ||
3. `[, arg1, arg2, ...]` *(Mixed)*: Arguments to invoke the method with. | ||
### Returns | ||
*(Array)*: A new array of values returned from each method invoked. | ||
### Example | ||
@@ -195,3 +223,3 @@ // invoke `reset` on all benchmarks | ||
// invoke `emit` with arguments | ||
Benchmark.invoke(benches, "emit", ["complete", b, c]); | ||
Benchmark.invoke(benches, "emit", "complete", listener); | ||
@@ -202,3 +230,3 @@ // invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks | ||
// invoke the `run` method | ||
"methodName": "run", | ||
"name": "run", | ||
@@ -211,2 +239,5 @@ // pass a single argument | ||
// called before any benchmarks have been invoked. | ||
"onStart": onStart, | ||
// called between invoking benchmarks | ||
@@ -219,3 +250,3 @@ "onCycle": onCycle, | ||
## <a name="static-isArray" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L710" title="View in source">Benchmark.isArray(value)</a> | ||
## <a name="static-isArray" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L827" title="View in source">Benchmark.isArray(value)</a> | ||
Determines if the given value is an array. | ||
@@ -230,3 +261,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-isCalibrated" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L720" title="View in source">Benchmark.isCalibrated()</a> | ||
## <a name="static-isCalibrated" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L837" title="View in source">Benchmark.isCalibrated()</a> | ||
Checks if calibration benchmarks have completed. | ||
@@ -238,3 +269,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-isClassOf" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L733" title="View in source">Benchmark.isClassOf(object, name)</a> | ||
## <a name="static-isClassOf" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L852" title="View in source">Benchmark.isClassOf(object, name)</a> | ||
Checks if an object is of the specified class. | ||
@@ -250,3 +281,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-isHostType" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L747" title="View in source">Benchmark.isHostType(object, property)</a> | ||
## <a name="static-isHostType" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L866" title="View in source">Benchmark.isHostType(object, property)</a> | ||
Host objects can return type values that are different from their actual | ||
@@ -264,3 +295,3 @@ data type. The objects we are concerned with usually return non-primitive | ||
## <a name="static-join" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L761" title="View in source">Benchmark.join(object, separator1, separator2)</a> | ||
## <a name="static-join" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L880" title="View in source">Benchmark.join(object, separator1, separator2)</a> | ||
Creates a string of joined array values or object key-value pairs. | ||
@@ -277,3 +308,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-map" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L783" title="View in source">Benchmark.map(array, callback)</a> | ||
## <a name="static-map" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L902" title="View in source">Benchmark.map(array, callback)</a> | ||
A generic bare-bones `Array#map` solution. | ||
@@ -289,7 +320,7 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-noop" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L795" title="View in source">Benchmark.noop()</a> | ||
## <a name="static-noop" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L914" title="View in source">Benchmark.noop()</a> | ||
A no-operation function. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="static-reduce" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L808" title="View in source">Benchmark.reduce(array, callback, accumulator)</a> | ||
## <a name="static-reduce" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L927" title="View in source">Benchmark.reduce(array, callback, accumulator)</a> | ||
A generic bare-bones `Array#reduce` solution. | ||
@@ -306,3 +337,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="static-trim" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L822" title="View in source">Benchmark.trim(string)</a> | ||
## <a name="static-trim" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L941" title="View in source">Benchmark.trim(string)</a> | ||
A generic bare-bones `String#trim` solution. | ||
@@ -319,107 +350,126 @@ <sup><code>[▲][1]</code></sup> | ||
# Benchmark.prototype | ||
## <a name="CALIBRATION_INDEX" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1575" title="View in source">Benchmark#CALIBRATION_INDEX</a> | ||
## <a name="CALIBRATION_INDEX" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1666" title="View in source">Benchmark#CALIBRATION_INDEX</a> | ||
*(Number)*: The index of the calibration benchmark to use when computing results. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="CYCLE_DELAY" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1582" title="View in source">Benchmark#CYCLE_DELAY</a> | ||
## <a name="CYCLE_DELAY" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1673" title="View in source">Benchmark#CYCLE_DELAY</a> | ||
*(Number)*: The delay between test cycles *(secs)*. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="DEFAULT_ASYNC" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1589" title="View in source">Benchmark#DEFAULT_ASYNC</a> | ||
## <a name="DEFAULT_ASYNC" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1680" title="View in source">Benchmark#DEFAULT_ASYNC</a> | ||
*(Boolean)*: A flag to indicate methods will run asynchronously by default. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="DETECT_INFINITY" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1596" title="View in source">Benchmark#DETECT_INFINITY</a> | ||
## <a name="DETECT_INFINITY" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1687" title="View in source">Benchmark#DETECT_INFINITY</a> | ||
*(Boolean)*: A flag to indicate protection against large run counts if Infinity ops/sec is detected. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="INIT_RUN_COUNT" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1603" title="View in source">Benchmark#INIT_RUN_COUNT</a> | ||
## <a name="INIT_RUN_COUNT" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1694" title="View in source">Benchmark#INIT_RUN_COUNT</a> | ||
*(Number)*: The default number of times to execute a test on a benchmark's first cycle. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="MAX_TIME_ELAPSED" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1610" title="View in source">Benchmark#MAX_TIME_ELAPSED</a> | ||
## <a name="MAX_TIME_ELAPSED" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1701" title="View in source">Benchmark#MAX_TIME_ELAPSED</a> | ||
*(Number)*: The maximum time a benchmark is allowed to run before finishing *(secs)*. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="MIN_TIME" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1617" title="View in source">Benchmark#MIN_TIME</a> | ||
## <a name="MIN_TIME" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1708" title="View in source">Benchmark#MIN_TIME</a> | ||
*(Number)*: The time needed to reduce the percent uncertainty of measurement to `1`% *(secs)*. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="MoE" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1624" title="View in source">Benchmark#MoE</a> | ||
*(Number)*: The margin of error. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="RME" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1631" title="View in source">Benchmark#RME</a> | ||
*(Number)*: The relative margin of error *(expressed as a percentage of the mean)*. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="SD" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1638" title="View in source">Benchmark#SD</a> | ||
*(Number)*: The sample standard deviation. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="SEM" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1645" title="View in source">Benchmark#SEM</a> | ||
*(Number)*: The standard error of the mean. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="aborted" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1687" title="View in source">Benchmark#aborted</a> | ||
## <a name="aborted" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1750" title="View in source">Benchmark#aborted</a> | ||
*(Boolean)*: A flag to indicate if the benchmark is aborted. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="count" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1652" title="View in source">Benchmark#count</a> | ||
## <a name="count" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1715" title="View in source">Benchmark#count</a> | ||
*(Number)*: The number of times a test was executed. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="created" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1659" title="View in source">Benchmark#created</a> | ||
## <a name="created" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1722" title="View in source">Benchmark#created</a> | ||
*(Number)*: A timestamp of when the benchmark was created. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="cycles" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1666" title="View in source">Benchmark#cycles</a> | ||
## <a name="cycles" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1729" title="View in source">Benchmark#cycles</a> | ||
*(Number)*: The number of cycles performed while benchmarking. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="error" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1673" title="View in source">Benchmark#error</a> | ||
## <a name="error" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1736" title="View in source">Benchmark#error</a> | ||
*(Object|Null)*: The error object if the test failed. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="hz" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1680" title="View in source">Benchmark#hz</a> | ||
## <a name="hz" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1743" title="View in source">Benchmark#hz</a> | ||
*(Number)*: The number of executions per second. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="persist" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1694" title="View in source">Benchmark#persist</a> | ||
## <a name="persist" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1757" title="View in source">Benchmark#persist</a> | ||
*(Mixed)*: A flag to indicate if results persist OR the number of days to persist. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="running" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1701" title="View in source">Benchmark#running</a> | ||
## <a name="running" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1764" title="View in source">Benchmark#running</a> | ||
*(Boolean)*: A flag to indicate if the benchmark is running. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="times" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1714" title="View in source">Benchmark#times</a> | ||
## <a name="stats" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1777" title="View in source">Benchmark#stats</a> | ||
*(Object)*: An object of stats including mean, margin or error, and standard deviation. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="MoE" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1784" title="View in source">Benchmark#stats.MoE</a> | ||
*(Number)*: The margin of error. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="RME" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1791" title="View in source">Benchmark#stats.RME</a> | ||
*(Number)*: The relative margin of error *(expressed as a percentage of the mean)*. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="SD" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1798" title="View in source">Benchmark#stats.SD</a> | ||
*(Number)*: The sample standard deviation. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="SEM" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1805" title="View in source">Benchmark#stats.SEM</a> | ||
*(Number)*: The standard error of the mean. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="mean" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1812" title="View in source">Benchmark#stats.mean</a> | ||
*(Number)*: The sample arithmetic mean. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="size" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1819" title="View in source">Benchmark#stats.size</a> | ||
*(Number)*: The sample size. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="variance" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1826" title="View in source">Benchmark#stats.variance</a> | ||
*(Number)*: The sample variance. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="times" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1834" title="View in source">Benchmark#times</a> | ||
*(Object)*: An object of timing data including cycle, elapsed, period, start, and stop. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="cycle" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1721" title="View in source">Benchmark#times.cycle</a> | ||
## <a name="cycle" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1841" title="View in source">Benchmark#times.cycle</a> | ||
*(Number)*: The time taken to complete the last cycle *(secs)* | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="elapsed" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1728" title="View in source">Benchmark#times.elapsed</a> | ||
## <a name="elapsed" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1848" title="View in source">Benchmark#times.elapsed</a> | ||
*(Number)*: The time taken to complete the benchmark *(secs)*. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="period" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1735" title="View in source">Benchmark#times.period</a> | ||
## <a name="period" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1855" title="View in source">Benchmark#times.period</a> | ||
*(Number)*: The time taken to execute the test once *(secs)*. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="start" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1742" title="View in source">Benchmark#times.start</a> | ||
## <a name="start" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1862" title="View in source">Benchmark#times.start</a> | ||
*(Number)*: A timestamp of when the benchmark started *(ms)*. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="stop" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1749" title="View in source">Benchmark#times.stop</a> | ||
## <a name="stop" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1869" title="View in source">Benchmark#times.stop</a> | ||
*(Number)*: A timestamp of when the benchmark finished *(ms)*. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="abort" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L905" title="View in source">Benchmark#abort()</a> | ||
## <a name="abort" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1025" title="View in source">Benchmark#abort()</a> | ||
Aborts the benchmark as well as in progress calibrations without recording times. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="addListener" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L835" title="View in source">Benchmark#addListener(type, listener)</a> | ||
### Returns | ||
*(Object)*: The benchmark instance. | ||
## <a name="addListener" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L954" title="View in source">Benchmark#addListener(type, listener)</a> | ||
Registers a single listener of a specified event type. | ||
@@ -435,3 +485,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="clone" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L935" title="View in source">Benchmark#clone(options)</a> | ||
## <a name="clone" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1056" title="View in source">Benchmark#clone(options)</a> | ||
Creates a cloned benchmark with the same test function and options. | ||
@@ -451,3 +501,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="compare" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L955" title="View in source">Benchmark#compare(other)</a> | ||
## <a name="compare" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1076" title="View in source">Benchmark#compare(other)</a> | ||
Determines if the benchmark's hertz is higher than another. | ||
@@ -462,3 +512,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="emit" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L849" title="View in source">Benchmark#emit(type)</a> | ||
## <a name="emit" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L968" title="View in source">Benchmark#emit(type)</a> | ||
Executes all registered listeners of a specified event type. | ||
@@ -470,7 +520,7 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="on" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1707" title="View in source">Benchmark#on</a> | ||
## <a name="on" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1770" title="View in source">Benchmark#on</a> | ||
Alias of [`Benchmark#addListener`](#addListener). | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="removeAllListeners" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L890" title="View in source">Benchmark#removeAllListeners(type)</a> | ||
## <a name="removeAllListeners" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1009" title="View in source">Benchmark#removeAllListeners(type)</a> | ||
Unregisters all listeners of a specified event type. | ||
@@ -485,3 +535,3 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="removeListener" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L872" title="View in source">Benchmark#removeListener(type, listener)</a> | ||
## <a name="removeListener" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L991" title="View in source">Benchmark#removeListener(type, listener)</a> | ||
Unregisters a single listener of a specified event type. | ||
@@ -497,7 +547,10 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="reset" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L966" title="View in source">Benchmark#reset()</a> | ||
## <a name="reset" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1098" title="View in source">Benchmark#reset()</a> | ||
Reset properties and abort if running. | ||
<sup><code>[▲][1]</code></sup> | ||
## <a name="run" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1285" title="View in source">Benchmark#run(async)</a> | ||
### Returns | ||
*(Object)*: The benchmark instance. | ||
## <a name="run" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1309" title="View in source">Benchmark#run(async)</a> | ||
Starts running the benchmark. | ||
@@ -509,3 +562,6 @@ <sup><code>[▲][1]</code></sup> | ||
## <a name="toString" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1003" title="View in source">Benchmark#toString()</a> | ||
### Returns | ||
*(Object)*: The benchmark instance. | ||
## <a name="toString" href="https://github.com/mathiasbynens/benchmark.js/blob/master/benchmark.js#L1139" title="View in source">Benchmark#toString()</a> | ||
Displays relevant benchmark information when coerced to a string. | ||
@@ -512,0 +568,0 @@ <sup><code>[▲][1]</code></sup> |
@@ -179,2 +179,3 @@ /*! | ||
* @private | ||
* @param {Object} e The event object. | ||
*/ | ||
@@ -196,7 +197,6 @@ function onClick(e) { | ||
* @private | ||
* @param {Object} bench The benchmark. | ||
*/ | ||
function onComplete(bench) { | ||
function onComplete() { | ||
setStatus(STATUS_TEXT.READY_AGAIN); | ||
ui.render(bench); | ||
ui.render(this); | ||
} | ||
@@ -207,6 +207,7 @@ | ||
* @private | ||
* @param {Object} bench The benchmark. | ||
*/ | ||
function onCycle(bench) { | ||
var cycles = bench.cycles; | ||
function onCycle() { | ||
var bench = this, | ||
cycles = bench.cycles; | ||
if (!bench.aborted) { | ||
@@ -243,2 +244,3 @@ setStatus(bench.name + ' × ' + formatNumber(bench.count) + ' (' + | ||
* @private | ||
* @param {Object} e The event object. | ||
*/ | ||
@@ -258,4 +260,8 @@ function onKeyUp(e) { | ||
addClass('run', 'show'); | ||
addClass('controls', 'show'); | ||
addClass('calgroup', 'show'); | ||
addListener('calibrate', 'click', onSetCalibrationState); | ||
addListener('run', 'click', onRun); | ||
setHTML('run', RUN_TEXT.READY); | ||
@@ -265,7 +271,13 @@ setHTML('user-agent', Benchmark.platform); | ||
// enable calibrations by default | ||
$('calibrate').checked = true; | ||
// answer spammer question | ||
$('question').value = 'no'; | ||
// show warning when Firebug is enabled | ||
// show warning and disable calibrations when Firebug is enabled | ||
if (typeof window.console != 'undefined' && typeof console.firebug == 'string') { | ||
$('calibrate').checked = false; | ||
onSetCalibrationState(); | ||
addClass('controls', 'reduce'); | ||
addClass('firebug', 'show'); | ||
@@ -282,45 +294,38 @@ } | ||
function onQueueComplete() { | ||
// populate result array (skipping unrun and errored benchmarks) | ||
var first, | ||
last, | ||
result = Benchmark.filter(ui.benchmarks, function(bench) { return bench.cycles; }); | ||
var benches = Benchmark.filter(ui.benchmarks, 'successful'), | ||
fastest = Benchmark.filter(benches, 'fastest'), | ||
slowest = Benchmark.filter(benches, 'slowest'); | ||
if (result.length > 1) { | ||
// sort descending fastest to slowest | ||
result.sort(function(a, b) { return b.compare(a); }); | ||
first = result[0]; | ||
last = result[result.length - 1]; | ||
// display contextual information | ||
each(benches, function(bench) { | ||
var percent, | ||
text = 'fastest', | ||
elResult = $(RESULTS_PREFIX + bench.id), | ||
elSpan = elResult.getElementsByTagName('span')[0]; | ||
// print contextual information | ||
each(result, function(bench) { | ||
var percent, | ||
text = 'fastest', | ||
elResult = $(RESULTS_PREFIX + bench.id), | ||
elSpan = elResult.getElementsByTagName('span')[0]; | ||
if (indexOf(fastest, bench) > -1) { | ||
// mark fastest | ||
addClass(elResult, text); | ||
} | ||
else { | ||
percent = Math.floor((1 - bench.hz / fastest[0].hz) * 100); | ||
text = percent + '% slower'; | ||
if (!bench.compare(first)) { | ||
// mark fastest | ||
addClass(elResult, text); | ||
// mark slowest | ||
if (indexOf(slowest, bench) > -1) { | ||
addClass(elResult, 'slowest'); | ||
} | ||
else { | ||
percent = Math.floor((1 - bench.hz / first.hz) * 100); | ||
text = percent + '% slower'; | ||
} | ||
// write ranking | ||
if (elSpan) { | ||
setHTML(elSpan, text); | ||
} else { | ||
appendHTML(elResult, '<span>' + text + '<\/span>'); | ||
} | ||
}); | ||
// mark slowest | ||
if (!bench.compare(last)) { | ||
addClass(elResult, 'slowest'); | ||
} | ||
} | ||
// write ranking | ||
if (elSpan) { | ||
setHTML(elSpan, text); | ||
} else { | ||
appendHTML(elResult, '<span>' + text + '<\/span>'); | ||
} | ||
}); | ||
// post results to Browserscope | ||
// post results to Browserscope | ||
if ($('calibrate').checked) { | ||
ui.browserscope.post(); | ||
} | ||
// all benchmarks are finished | ||
@@ -334,2 +339,3 @@ ui.running = false; | ||
* @private | ||
* @param {Object} e The event object. | ||
*/ | ||
@@ -347,2 +353,17 @@ function onRun(e) { | ||
/** | ||
* The "calibrate" checkbox click event handler used to enable/disable calibrations. | ||
* @private | ||
*/ | ||
function onSetCalibrationState() { | ||
var length = Benchmark.CALIBRATIONS.length; | ||
if ($('calibrate').checked) { | ||
if (!length) { | ||
Benchmark.CALIBRATIONS = cache.CALIBRATIONS; | ||
} | ||
} else if (length) { | ||
cache.CALIBRATIONS = [Benchmark.CALIBRATIONS, Benchmark.CALIBRATIONS = []][0]; | ||
} | ||
} | ||
/*--------------------------------------------------------------------------*/ | ||
@@ -446,6 +467,6 @@ | ||
cell.title = 'Ran ' + formatNumber(bench.count) + ' times in ' + | ||
bench.times.cycle.toFixed(2) + ' seconds.'; | ||
bench.times.cycle.toFixed(3) + ' seconds.'; | ||
setHTML(cell, hz == Infinity ? hz : | ||
formatNumber(hz) + ' <small>±' + bench.RME.toFixed(2) + '%<\/small>'); | ||
formatNumber(hz) + ' <small>±' + bench.stats.RME.toFixed(2) + '%<\/small>'); | ||
} | ||
@@ -492,3 +513,3 @@ // status: pending | ||
invoke(queue, { | ||
'methodName': 'run', | ||
'name': 'run', | ||
'queued': true, | ||
@@ -495,0 +516,0 @@ 'onComplete': onQueueComplete |
{ | ||
"name": "benchmark", | ||
"version": "0.1.338", | ||
"version": "0.1.339", | ||
"description": "A benchmarking library that works on nearly all JavaScript platforms, supports high-resolution timers, and returns statistically significant results.", | ||
@@ -5,0 +5,0 @@ "homepage": "http://benchmarkjs.com/", |
@@ -1,2 +0,1 @@ | ||
(function(window, document) { | ||
@@ -59,3 +58,3 @@ | ||
var clone = bench.clone(); | ||
clone.hz = Math.round(bench.hz - bench.MoE); | ||
clone.hz = Math.round(bench.hz - bench.stats.MoE); | ||
return clone; | ||
@@ -62,0 +61,0 @@ }); |
@@ -9,2 +9,4 @@ # Benchmark.js | ||
For a list of upcoming features, check out our [roadmap](https://github.com/mathiasbynens/benchmark.js/wiki/Roadmap). | ||
## Installation and usage | ||
@@ -36,2 +38,45 @@ | ||
Usage example: | ||
function testA() { | ||
/o/.test("Hello World!"); | ||
} | ||
function testB() { | ||
"Hello World!".indexOf("o") > -1; | ||
} | ||
var benches = [ | ||
new Benchmark("RegExp#test", testA), | ||
new Benchmark("String#indexOf", testB) | ||
]; | ||
// add listeners | ||
Benchmark.invoke(benches, "on", "complete", function() { | ||
console.log( this.toString() ); | ||
}); | ||
// run benchmarks (async) | ||
Benchmark.invoke(benches, { | ||
"name": "run", | ||
"args": true, | ||
"onComplete": function() { | ||
var a = benches[0], | ||
b = benches[1], | ||
rank = a.compare(b); | ||
// report results | ||
console.log( | ||
a.name + " is " + | ||
(rank == 0 ? " <indeterminate> " : rank > 0 ? "faster" : "slower") + | ||
" than " + b.name | ||
); | ||
} | ||
}); | ||
// logs: | ||
// > RegExp#test × 4,161,532 ±0.99% (59 cycles) | ||
// > String#indexOf × 6,139,623 ±1.00% (131 cycles) | ||
// > RegExp#test is slower than String#indexOf | ||
## Cloning this repo | ||
@@ -38,0 +83,0 @@ |
(function() { | ||
// load Benchmark | ||
var Benchmark = require('../../benchmark/benchmark.js').Benchmark; | ||
var Benchmark = require('../benchmark.js').Benchmark; | ||
@@ -6,0 +6,0 @@ // hookup calibration notice |
(function() { | ||
// load Benchmark | ||
var Benchmark = require('../../benchmark/benchmark.js'); | ||
var Benchmark = require('../benchmark.js'); | ||
@@ -6,0 +6,0 @@ // hookup calibration notice |
(function(global) { | ||
// load Benchmark | ||
load('../benchmark/benchmark.js'); | ||
load('../benchmark.js'); | ||
@@ -6,0 +6,0 @@ // hookup calibration notice |
(function() { | ||
// load Benchmark | ||
var Benchmark = require('../../benchmark/benchmark.js').Benchmark; | ||
var Benchmark = require('../benchmark.js').Benchmark; | ||
@@ -6,0 +6,0 @@ // hookup calibration notice |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
287867
32
6638
97