Skip to content

Instantly share code, notes, and snippets.

@mckamey
Created October 27, 2011 00:24
Show Gist options
  • Save mckamey/1318433 to your computer and use it in GitHub Desktop.
Save mckamey/1318433 to your computer and use it in GitHub Desktop.
Simple JS Perf Timer API
/**
* perf.js
* Simple JS Timer API
*
* @public
* @param {number} alpha weight for EWMA trends (default: 0.2)
* @this {Perf}
* @constructor
*/
var Perf = function(alpha) {
"use strict";
// private members ----------
// bound alpha within 0-1, default to 0.2
alpha = (alpha > 0) ? ((alpha < 1) ? alpha : 1) : 0.2;
/**
* Date.now() polyfill
*
* @private
* @type {function()}
*/
var now = Date.now || function() { return new Date().getTime(); };
/**
* Starting clock (ms since UNIX epoch)
*
* @private
* @type {Object}
*/
var start = {};
/**
* Most recent measurement
*
* @private
* @type {number}
*/
var last = 0;
/**
* Sum of measurements
*
* @private
* @type {number}
*/
var sum = 0;
/**
* Count of measurements
*
* @private
* @type {number}
*/
var count = 0;
/**
* Exponentially Weighted Moving Average
*
* @private
* @type {number}
*/
var ewma = 0;
// public members ----------
return {
/**
* Gets most recent timing in ms
*
* @public
* @param {number} digits the number of digits for formatting
* @return {string}
*/
last: function(digits) {
return last.toFixed(digits || 0);
},
/**
* Gets the average timing in ms
*
* @public
* @param {number} digits the number of digits for formatting
* @return {string}
*/
mean: function(digits) {
return (count ? (sum / count) : 0).toFixed(digits || 0);
},
/**
* Gets sum of all timings in ms
*
* @public
* @param {number} digits the number of digits for formatting
* @return {string}
*/
sum: function(digits) {
return sum.toFixed(digits || 0);
},
/**
* Gets weighted timing trend in ms
*
* @public
* @param {number} digits the number of digits for formatting
* @return {string}
*/
trend: function(digits) {
return ewma.toFixed(digits || 0);
},
/**
* Begins timing
*
* @public
*/
start: function(key) {
start[key || ''] = now();
},
/**
* Ends timing
*
* @public
*/
stop: function(key) {
key = key || '';
if (!start[key]) { return; }
// last
last = now() - start[key];
delete start[key];
// exponentially weighted moving average
ewma = count ? (alpha*last) + ((1-alpha)*ewma) : last;
// mean
sum += last;
count++;
},
/**
* Ends timing but doesn't record
*
* @public
*/
cancel: function(key) {
key = key || '';
if (!start[key]) { return; }
delete start[key];
},
/**
* Clears all statistics
*
* @public
*/
reset: function() {
start = {};
last = sum = count = ewma = 0;
},
/**
* Creates a unique key
*
* @public
*/
unique: function() {
return (now()+Math.random()).toString(36);
}
};
};
var Perf=function(c){var c=0<c?1>c?c:1:0.2,h=Date.now||function(){return(new Date).getTime()},b={},d=0,e=0,f=0,g=0;return{last:function(a){return d.toFixed(a||0)},mean:function(a){return(f?e/f:0).toFixed(a||0)},sum:function(a){return e.toFixed(a||0)},trend:function(a){return g.toFixed(a||0)},start:function(a){b[a||""]=h()},stop:function(a){a=a||"";b[a]&&(d=h()-b[a],delete b[a],g=f?c*d+(1-c)*g:d,e+=d,f++)},cancel:function(a){a=a||"";b[a]&&delete b[a]},reset:function(){b={};d=e=f=g=0},unique:function(){return(h()+
Math.random()).toString(36)}}};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment