summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2013-02-11 23:28:48 -0800
committerisaacs <i@izs.me>2013-02-19 14:14:30 -0800
commitaa2edd4b89c51836424b211db756ba907230b58b (patch)
treea3c267ffc862061d94d09d9bb6679e131dbbe79a
parent37077de83dbb97f1b51839fb0ebff608aa9ea3c8 (diff)
downloadnodejs-aa2edd4b89c51836424b211db756ba907230b58b.tar.gz
nodejs-aa2edd4b89c51836424b211db756ba907230b58b.tar.bz2
nodejs-aa2edd4b89c51836424b211db756ba907230b58b.zip
bench: A compare script for analyzing benchmarks
-rw-r--r--benchmark/compare.js116
1 files changed, 116 insertions, 0 deletions
diff --git a/benchmark/compare.js b/benchmark/compare.js
new file mode 100644
index 000000000..05733a1e3
--- /dev/null
+++ b/benchmark/compare.js
@@ -0,0 +1,116 @@
+var usage = 'node benchmark/compare.js <node-binary1> <node-binary2>';
+
+var show = 'both';
+var nodes = [];
+for (var i = 2; i < process.argv.length; i++) {
+ var arg = process.argv[i];
+ switch (arg) {
+ case '--red': case '-r':
+ show = show === 'green' ? 'both' : 'red';
+ break;
+ case '--green': case '-g':
+ show = show === 'red' ? 'both' : 'green';
+ break;
+ default:
+ nodes.push(arg);
+ break;
+ }
+}
+
+var runBench = process.env.NODE_BENCH || 'bench';
+
+if (nodes.length !== 2)
+ return console.error('usage:\n %s', usage);
+
+var spawn = require('child_process').spawn;
+var results = {};
+var n = 2;
+
+run();
+
+function run() {
+ if (n === 0)
+ return compare();
+
+ n--;
+
+ var node = nodes[n];
+ console.error('running %s', node);
+ var env = {};
+ for (var i in process.env)
+ env[i] = process.env[i];
+ env.NODE = node;
+ var child = spawn('make', [ runBench ], { env: env });
+
+ var out = '';
+ child.stdout.setEncoding('utf8');
+ child.stdout.on('data', function(c) {
+ out += c;
+ });
+
+ child.stderr.pipe(process.stderr);
+
+ child.on('close', function(code) {
+ if (code) {
+ console.error('%s exited with code=%d', node, code);
+ process.exit(code);
+ } else {
+ out.trim().split(/\r?\n/).forEach(function(line) {
+ line = line.trim();
+ if (!line)
+ return;
+
+ var s = line.split(':');
+ var num = +s.pop();
+ if (!num && num !== 0)
+ return
+
+ line = s.join(':');
+ var res = results[line] = results[line] || {};
+ res[node] = num;
+ });
+
+ run();
+ }
+ });
+}
+
+function compare() {
+ // each result is an object with {"foo.js arg=bar":12345,...}
+ // compare each thing, and show which node did the best.
+ // node[0] is shown in green, node[1] shown in red.
+ var green = '\033[1;32m';
+ var red = '\033[1;31m';
+ var reset = '\033[m';
+ var maxLen = -Infinity;
+ var util = require('util');
+ Object.keys(results).map(function(bench) {
+ var res = results[bench];
+ var n0 = res[nodes[0]];
+ var n1 = res[nodes[1]];
+
+ var pct = ((n0 - n1) / ((n0 + n1) / 2) * 100).toFixed(2);
+
+ var g = n0 > n1 ? green : '';
+ var r = n0 > n1 ? '' : red;
+ var c = r || g;
+
+ if (show === 'green' && !g || show === 'red' && !r)
+ return;
+
+ var r0 = util.format('%s%s: %d%s', g, nodes[0], n0, reset);
+ var r1 = util.format('%s%s: %d%s', r, nodes[1], n1, reset);
+ var pct = c + pct + '%' + reset;
+ var l = util.format('%s: %s %s', bench, r0, r1);
+ maxLen = Math.max(l.length + pct.length, maxLen);
+ return [l, pct];
+ }).filter(function(l) {
+ return l;
+ }).forEach(function(line) {
+ var l = line[0];
+ var pct = line[1];
+ var dotLen = maxLen - l.length - pct.length + 2;
+ var dots = ' ' + new Array(Math.max(0, dotLen)).join('.') + ' ';
+ console.log(l + dots + pct);
+ });
+}