Created
March 22, 2014 04:36
-
-
Save mindplay-dk/9701123 to your computer and use it in GitHub Desktop.
JavaScript benchmark function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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