Skip to content

Instantly share code, notes, and snippets.

@mindplay-dk
Created March 22, 2014 04:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mindplay-dk/9701123 to your computer and use it in GitHub Desktop.
Save mindplay-dk/9701123 to your computer and use it in GitHub Desktop.
JavaScript benchmark function
// noprotect
/**
* JavaScript benchmark function
*
* Usage: console.log(bench(function(){ ... }));
*/
bench = (function() {
var
MIN_TIME = 3000, // benchmark for at least this long (msec)
MIN_MARKS = 30, // benchmark at least this many times
MIN_ELAPSED = 100; // iterate for at least this long (msec) between marks
var _baseline = 0; // overhead for an empty function call
/**
* Compute the minimum number of iterations required to run
* for at least MIN_ELAPSED msec between marks.
*/
function min_it(fn) {
var
it = 0,
elapsed = 0;
start = new Date().getTime();
while (elapsed < MIN_ELAPSED) {
fn();
it += 1;
elapsed = (new Date().getTime()) - start;
}
return it;
}
/**
* Compute the weighted average of a given series of values.
*/
function weighted_average(values) {
var
sum = 0,
avg,
error = [],
max_error = 0,
i,
total_weight = 0,
weighted_sum = 0,
weight;
for (i=0; i<values.length; i++) {
sum += values[i];
}
avg = sum / values.length;
for (i=0; i<values.length; i++) {
error[i] = Math.abs(avg - values[i]);
max_error = Math.max(error[i], max_error);
}
for (i=0; i<values.length; i++) {
weight = 1 - (error[i] / max_error);
weight = weight * weight; // square
total_weight += weight;
weighted_sum += weight * values[i];
}
return weighted_sum / total_weight;
}
/**
* Benchmark the given function - returns time per iteration, in milliseconds.
*/
function bench(fn) {
var
time = [],
elapsed = 0,
marks = -1, // don't mark the first run
start,
end,
it,
num_it = min_it(fn);
while (elapsed < MIN_TIME || marks < MIN_MARKS) {
start = new Date().getTime();
for (it=0; it<num_it; it++) {
fn();
}
end = new Date().getTime();
marks += 1;
if (marks > 0) {
time.push((end - start) / num_it);
elapsed += end - start;
}
}
var weighted = weighted_average(time);
return {
average: Math.max(0, weighted - _baseline),
elapsed: elapsed,
iterations: num_it,
marks: marks
};
}
_baseline = bench(function () {}).average;
return bench;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment