src: move debug agent from deps/ to src/
[platform/upstream/nodejs.git] / benchmark / compare.js
1 var usage = 'node benchmark/compare.js ' +
2             '<node-binary1> <node-binary2> ' +
3             '[--html] [--red|-r] [--green|-g]';
4
5 var show = 'both';
6 var nodes = [];
7 var html = false;
8
9 for (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;
18     case '--html':
19       html = true;
20       break;
21     case '-h': case '-?': case '--help':
22       console.log(usage);
23       process.exit(0);
24     default:
25       nodes.push(arg);
26       break;
27   }
28 }
29
30 if (!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">';
39   var red = '<span style="background-color:#f00;color:#fff">';
40   var reset = '</span>';
41   var end = '</pre>';
42 }
43
44 var runBench = process.env.NODE_BENCH || 'bench';
45
46 if (nodes.length !== 2)
47   return console.error('usage:\n  %s', usage);
48
49 var spawn = require('child_process').spawn;
50 var results = {};
51 var toggle = 1;
52 var r = (+process.env.NODE_BENCH_RUNS || 1) * 2;
53
54 run();
55 function run() {
56   if (--r < 0)
57     return compare();
58   toggle = ++toggle % 2;
59
60   var node = nodes[toggle];
61   console.error('running %s', node);
62   var env = {};
63   for (var i in process.env)
64     env[i] = process.env[i];
65   env.NODE = node;
66
67   var out = '';
68   var child = spawn('make', [runBench], { env: env });
69   child.stdout.setEncoding('utf8');
70   child.stdout.on('data', function(c) {
71     out += c;
72   });
73
74   child.stderr.pipe(process.stderr);
75
76   child.on('close', function(code) {
77     if (code) {
78       console.error('%s exited with code=%d', node, code);
79       process.exit(code);
80     } else {
81       out.trim().split(/\r?\n/).forEach(function(line) {
82         line = line.trim();
83         if (!line)
84           return;
85
86         var s = line.split(':');
87         var num = +s.pop();
88         if (!num && num !== 0)
89           return;
90
91         line = s.join(':');
92         var res = results[line] = results[line] || {};
93         res[node] = res[node] || [];
94         res[node].push(num);
95       });
96
97       run();
98     }
99   });
100 }
101
102 function compare() {
103   // each result is an object with {"foo.js arg=bar":12345,...}
104   // compare each thing, and show which node did the best.
105   // node[0] is shown in green, node[1] shown in red.
106   var maxLen = -Infinity;
107   var util = require('util');
108   console.log(start);
109
110   Object.keys(results).map(function(bench) {
111     var res = results[bench];
112     var n0 = avg(res[nodes[0]]);
113     var n1 = avg(res[nodes[1]]);
114
115     var pct = ((n0 - n1) / n1 * 100).toFixed(2);
116
117     var g = n0 > n1 ? green : '';
118     var r = n0 > n1 ? '' : red;
119     var c = r || g;
120
121     if (show === 'green' && !g || show === 'red' && !r)
122       return;
123
124     var r0 = util.format('%s%s: %d%s', g, nodes[0], n0.toPrecision(5), g ? reset : '');
125     var r1 = util.format('%s%s: %d%s', r, nodes[1], n1.toPrecision(5), r ? reset : '');
126     var pct = c + pct + '%' + reset;
127     var l = util.format('%s: %s %s', bench, r0, r1);
128     maxLen = Math.max(l.length + pct.length, maxLen);
129     return [l, pct];
130   }).filter(function(l) {
131     return l;
132   }).forEach(function(line) {
133     var l = line[0];
134     var pct = line[1];
135     var dotLen = maxLen - l.length - pct.length + 2;
136     var dots = ' ' + new Array(Math.max(0, dotLen)).join('.') + ' ';
137     console.log(l + dots + pct);
138   });
139   console.log(end);
140 }
141
142 function avg(list) {
143   if (list.length >= 3) {
144     list = list.sort();
145     var q = Math.floor(list.length / 4) || 1;
146     list = list.slice(q, -q);
147   }
148   return list.reduce(function(a, b) {
149     return a + b;
150   }, 0) / list.length;
151 }