blob: d2221eeb78d808e5e865d23d72044ccc364b9336 [file] [log] [blame]
isaacsdb5d58e2013-03-06 20:32:591var usage = 'node benchmark/compare.js ' +
2 '<node-binary1> <node-binary2> ' +
3 '[--html] [--red|-r] [--green|-g]';
isaacsaa2edd42013-02-12 07:28:484
5var show = 'both';
6var nodes = [];
isaacs087c4372013-02-13 18:47:297var html = false;
8
isaacsaa2edd42013-02-12 07:28:489for (var i = 2; i < process.argv.length; i++) {
10 var arg = process.argv[i];
11 switch (arg) {
12 case '--red': case '-r':
13 show = show === 'green' ? 'both' : 'red';
14 break;
15 case '--green': case '-g':
16 show = show === 'red' ? 'both' : 'green';
17 break;
isaacs087c4372013-02-13 18:47:2918 case '--html':
19 html = true;
20 break;
21 case '-h': case '-?': case '--help':
22 console.log(usage);
23 process.exit(0);
isaacsaa2edd42013-02-12 07:28:4824 default:
25 nodes.push(arg);
26 break;
27 }
28}
29
isaacs087c4372013-02-13 18:47:2930if (!html) {
31 var start = '';
32 var green = '\033[1;32m';
33 var red = '\033[1;31m';
34 var reset = '\033[m';
35 var end = '';
36} else {
37 var start = '<pre style="background-color:#333;color:#eee">';
38 var green = '<span style="background-color:#0f0;color:#000">';
isaacs053e02e2013-02-20 17:17:2939 var red = '<span style="background-color:#f00;color:#fff">';
isaacs087c4372013-02-13 18:47:2940 var reset = '</span>';
41 var end = '</pre>';
42}
43
isaacsaa2edd42013-02-12 07:28:4844var runBench = process.env.NODE_BENCH || 'bench';
45
46if (nodes.length !== 2)
isaacsdb5d58e2013-03-06 20:32:5947 return console.error('usage:\n %s', usage);
isaacsaa2edd42013-02-12 07:28:4848
49var spawn = require('child_process').spawn;
50var results = {};
isaacsdb5d58e2013-03-06 20:32:5951var n = 1;
isaacsaa2edd42013-02-12 07:28:4852
53run();
54
isaacsdb5d58e2013-03-06 20:32:5955var RUNS = +process.env.NODE_BENCH_RUNS || 1;
56var r = RUNS;
isaacsaa2edd42013-02-12 07:28:4857function run() {
isaacsdb5d58e2013-03-06 20:32:5958 // Flip back and forth between the two binaries.
59 if (n === 1) {
60 n--;
61 } else {
62 r--;
63 if (r === 0)
64 return compare();
65 else
66 n++;
67 }
isaacsaa2edd42013-02-12 07:28:4868
isaacsdb5d58e2013-03-06 20:32:5969 if (n === -1)
70 return compare();
isaacsaa2edd42013-02-12 07:28:4871
isaacsdb5d58e2013-03-06 20:32:5972 var node = nodes[n];
isaacsaa2edd42013-02-12 07:28:4873 console.error('running %s', node);
isaacsdb5d58e2013-03-06 20:32:5974 var env = {};
isaacsaa2edd42013-02-12 07:28:4875 for (var i in process.env)
76 env[i] = process.env[i];
77 env.NODE = node;
isaacsdb5d58e2013-03-06 20:32:5978 var child = spawn('make', [runBench], { env: env });
isaacsaa2edd42013-02-12 07:28:4879
isaacsdb5d58e2013-03-06 20:32:5980 var out = '';
81 child.stdout.setEncoding('utf8');
82 child.stdout.on('data', function(c) {
83 out += c;
84 });
isaacsaa2edd42013-02-12 07:28:4885
86 child.stderr.pipe(process.stderr);
87
isaacsdb5d58e2013-03-06 20:32:5988 child.on('close', function(code) {
89 if (code) {
90 console.error('%s exited with code=%d', node, code);
91 process.exit(code);
92 } else {
93 out.trim().split(/\r?\n/).forEach(function(line) {
isaacsaa2edd42013-02-12 07:28:4894 line = line.trim();
95 if (!line)
96 return;
97
isaacsdb5d58e2013-03-06 20:32:5998 var s = line.split(':');
99 var num = +s.pop();
100 if (!num && num !== 0)
101 return;
isaacsaa2edd42013-02-12 07:28:48102
isaacsdb5d58e2013-03-06 20:32:59103 line = s.join(':');
104 var res = results[line] = results[line] || {};
105 res[node] = res[node] || [];
106 res[node].push(num);
107 });
isaacsaa2edd42013-02-12 07:28:48108
isaacsdb5d58e2013-03-06 20:32:59109 run();
110 }
111 });
isaacsaa2edd42013-02-12 07:28:48112}
113
114function compare() {
isaacsdb5d58e2013-03-06 20:32:59115 // each result is an object with {"foo.js arg=bar":12345,...}
116 // compare each thing, and show which node did the best.
isaacsaa2edd42013-02-12 07:28:48117 // node[0] is shown in green, node[1] shown in red.
isaacsaa2edd42013-02-12 07:28:48118 var maxLen = -Infinity;
119 var util = require('util');
isaacs087c4372013-02-13 18:47:29120 console.log(start);
121
isaacsdb5d58e2013-03-06 20:32:59122 Object.keys(results).map(function(bench) {
isaacsaa2edd42013-02-12 07:28:48123 var res = results[bench];
isaacsdb5d58e2013-03-06 20:32:59124 var n0 = avg(res[nodes[0]]);
125 var n1 = avg(res[nodes[1]]);
isaacsaa2edd42013-02-12 07:28:48126
isaacs035aa6b2013-02-13 18:48:55127 var pct = ((n0 - n1) / n1 * 100).toFixed(2);
isaacsaa2edd42013-02-12 07:28:48128
129 var g = n0 > n1 ? green : '';
130 var r = n0 > n1 ? '' : red;
131 var c = r || g;
132
133 if (show === 'green' && !g || show === 'red' && !r)
134 return;
135
isaacsdb5d58e2013-03-06 20:32:59136 var r0 = util.format('%s%s: %d%s', g, nodes[0], n0, g ? reset : '');
137 var r1 = util.format('%s%s: %d%s', r, nodes[1], n1, r ? reset : '');
isaacsaa2edd42013-02-12 07:28:48138 var pct = c + pct + '%' + reset;
139 var l = util.format('%s: %s %s', bench, r0, r1);
140 maxLen = Math.max(l.length + pct.length, maxLen);
141 return [l, pct];
142 }).filter(function(l) {
143 return l;
144 }).forEach(function(line) {
145 var l = line[0];
146 var pct = line[1];
147 var dotLen = maxLen - l.length - pct.length + 2;
148 var dots = ' ' + new Array(Math.max(0, dotLen)).join('.') + ' ';
149 console.log(l + dots + pct);
150 });
isaacs087c4372013-02-13 18:47:29151 console.log(end);
isaacsaa2edd42013-02-12 07:28:48152}
isaacsdb5d58e2013-03-06 20:32:59153
154function avg(list) {
155 if (list.length >= 3) {
156 list = list.sort();
157 var q = Math.floor(list.length / 4) || 1;
158 list = list.slice(q, -q);
159 }
160 return (list.reduce(function(a, b) {
161 return a + b;
162 }, 0) / list.length).toPrecision(5);
163}