(function(uubench){ function Bench(id, test, options, callback) { this.id = id; this.options = options; this.test = test; this.loop = test.length > 1; this.callback = callback; } Bench.prototype.run = function(iter) { var self = this, fn = self.test, checkfn = self.options.type === "adaptive" ? adaptive : fixed, i = iter, pend = i, min = self.options.min, start; if (self.loop) { pend = 1; start = new Date(); fn(checkfn, i); } else { start = new Date(); while (i--) { fn(checkfn); } } function fixed() { if (--pend === 0) { var elapsed = new Date() - start; self.callback({iterations: iter, elapsed: elapsed}); } } function adaptive() { if (--pend === 0) { var elapsed = new Date() - start; if (elapsed < min) { self.run(iter*2); } else { self.callback({iterations: iter, elapsed: elapsed}); } } } } uubench.Bench = Bench; uubench.defaults = { type: "adaptive", // adaptive or fixed iterations: 10, // starting iterations min: 100, // minimum run time (ms) - adaptive only delay: 100 // delay between tests (ms) } function Suite(opts) { for (var key in uubench.defaults) { if (opts[key] === undefined) { opts[key] = uubench.defaults[key]; } } this.options = opts; this.tests = []; } Suite.prototype.bench = function(name, fn) { var self = this; self.tests.push(new Bench(name, fn, this.options, function(stats) { self.emit("result", name, stats); self.pending--; self.check(); })); } Suite.prototype.run = function() { if (this.pending) return; var self = this, len = self.tests.length; self.emit("start", self.tests); self.start = new Date().getTime(); self.pending = len; for (var i=0; i