var Emitter = require('events').EventEmitter var util = require('util') module.exports = Audit function Audit(options) { options = options || {} this.iters = options.iterations || 1e3 this.pause = options.pause || 100 this.audits = [] } util.inherits(Audit, Emitter) Audit.prototype.makeAudit = function(name, audit, async) { if (!audit) { audit = name name = 'Nameless-'+this.audits.length } this.audits.push({ name:name, fn:audit, async:async }) return this } Audit.prototype.async = function(name, audit) { return this.makeAudit(name, audit, true) } Audit.prototype.sync = function(name, audit) { return this.makeAudit(name, audit, false) } Audit.prototype.runAudit = function(audit, fn) { var iters = this.iters var times = [] ;(function next(i) { if (i > iters) { return fn(audit.name, times) } var then = Date.now() if (audit.async) { audit.fn(function() { times.push(Date.now() - then) next(++i) }) }else { var res = audit.fn() times.push(Date.now() - then) next(++i) } })(0) } Audit.prototype.run = function(fn) { var self = this , audits = this.audits , iters = this.iters , pause = this.pause , stats = {} , count = 0 ;(function next(i) { var audit = audits[i] self.emit('auditing', audit.name) self.runAudit(audit, function() { auditComplete.apply(this, arguments) if (++i >= audits.length) { return complete() } setTimeout(function() { next(i) }, pause) }) })(0) function complete() { self.emit('complete', stats) } function auditComplete(name, times) { var _stats = getStats(times) var auditStats = { name:name, elapsed:_stats.elapsed+'ms', iterations:iters, opsPerSecond:(iters / _stats.elapsed) * 1000, mode:_stats.mode, median:_stats.median, mean:_stats.mean, max:_stats.max, min:_stats.min } self.emit('auditcomplete', auditStats) stats[name] = auditStats } } function getStats(times) { var elapsed = times.reduce(function(a, b) { return a + b }) var mode = [0, ''] , median = times[~~(times.length/2)] , mean = elapsed / times.length , max = [times[0], 0+'ind'] , min = [times[0], 0+'ind'] , maxOcc = 0 , freq = {} for (var i=0, len=times.length;i max[0]) { max = [item, i+'ind'] }else if (item < min[0]) { min = [item, i+'ind'] } })() } for (k in freq) { if (freq[k] > maxOcc) { mode = [k+'ms', freq[k]+'occ'] maxOcc = k } } return { elapsed:elapsed, frequency:freq, mode:mode, median:median+'ms', mean:mean+'ms', max:[max[0]+'ms', max[1]], min:[min[0]+'ms', min[1]] } }