isaacs | 087c437 | 2013-02-13 18:47:29 | [diff] [blame] | 1 | var usage = 'node benchmark/compare.js <node-binary1> <node-binary2> [--html] [--red|-r] [--green|-g]'; |
isaacs | aa2edd4 | 2013-02-12 07:28:48 | [diff] [blame] | 2 | |
| 3 | var show = 'both'; |
| 4 | var nodes = []; |
isaacs | 087c437 | 2013-02-13 18:47:29 | [diff] [blame] | 5 | var html = false; |
| 6 | |
isaacs | aa2edd4 | 2013-02-12 07:28:48 | [diff] [blame] | 7 | for (var i = 2; i < process.argv.length; i++) { |
| 8 | var arg = process.argv[i]; |
| 9 | switch (arg) { |
| 10 | case '--red': case '-r': |
| 11 | show = show === 'green' ? 'both' : 'red'; |
| 12 | break; |
| 13 | case '--green': case '-g': |
| 14 | show = show === 'red' ? 'both' : 'green'; |
| 15 | break; |
isaacs | 087c437 | 2013-02-13 18:47:29 | [diff] [blame] | 16 | case '--html': |
| 17 | html = true; |
| 18 | break; |
| 19 | case '-h': case '-?': case '--help': |
| 20 | console.log(usage); |
| 21 | process.exit(0); |
isaacs | aa2edd4 | 2013-02-12 07:28:48 | [diff] [blame] | 22 | default: |
| 23 | nodes.push(arg); |
| 24 | break; |
| 25 | } |
| 26 | } |
| 27 | |
isaacs | 087c437 | 2013-02-13 18:47:29 | [diff] [blame] | 28 | if (!html) { |
| 29 | var start = ''; |
| 30 | var green = '\033[1;32m'; |
| 31 | var red = '\033[1;31m'; |
| 32 | var reset = '\033[m'; |
| 33 | var end = ''; |
| 34 | } else { |
| 35 | var start = '<pre style="background-color:#333;color:#eee">'; |
| 36 | var green = '<span style="background-color:#0f0;color:#000">'; |
isaacs | 053e02e | 2013-02-20 17:17:29 | [diff] [blame] | 37 | var red = '<span style="background-color:#f00;color:#fff">'; |
isaacs | 087c437 | 2013-02-13 18:47:29 | [diff] [blame] | 38 | var reset = '</span>'; |
| 39 | var end = '</pre>'; |
| 40 | } |
| 41 | |
isaacs | aa2edd4 | 2013-02-12 07:28:48 | [diff] [blame] | 42 | var runBench = process.env.NODE_BENCH || 'bench'; |
| 43 | |
| 44 | if (nodes.length !== 2) |
| 45 | return console.error('usage:\n %s', usage); |
| 46 | |
| 47 | var spawn = require('child_process').spawn; |
| 48 | var results = {}; |
| 49 | var n = 2; |
| 50 | |
| 51 | run(); |
| 52 | |
| 53 | function run() { |
| 54 | if (n === 0) |
| 55 | return compare(); |
| 56 | |
| 57 | n--; |
| 58 | |
| 59 | var node = nodes[n]; |
| 60 | console.error('running %s', node); |
| 61 | var env = {}; |
| 62 | for (var i in process.env) |
| 63 | env[i] = process.env[i]; |
| 64 | env.NODE = node; |
| 65 | var child = spawn('make', [ runBench ], { env: env }); |
| 66 | |
| 67 | var out = ''; |
| 68 | child.stdout.setEncoding('utf8'); |
| 69 | child.stdout.on('data', function(c) { |
| 70 | out += c; |
| 71 | }); |
| 72 | |
| 73 | child.stderr.pipe(process.stderr); |
| 74 | |
| 75 | child.on('close', function(code) { |
| 76 | if (code) { |
| 77 | console.error('%s exited with code=%d', node, code); |
| 78 | process.exit(code); |
| 79 | } else { |
| 80 | out.trim().split(/\r?\n/).forEach(function(line) { |
| 81 | line = line.trim(); |
| 82 | if (!line) |
| 83 | return; |
| 84 | |
| 85 | var s = line.split(':'); |
| 86 | var num = +s.pop(); |
| 87 | if (!num && num !== 0) |
| 88 | return |
| 89 | |
| 90 | line = s.join(':'); |
| 91 | var res = results[line] = results[line] || {}; |
| 92 | res[node] = num; |
| 93 | }); |
| 94 | |
| 95 | run(); |
| 96 | } |
| 97 | }); |
| 98 | } |
| 99 | |
| 100 | function compare() { |
| 101 | // each result is an object with {"foo.js arg=bar":12345,...} |
| 102 | // compare each thing, and show which node did the best. |
| 103 | // node[0] is shown in green, node[1] shown in red. |
isaacs | aa2edd4 | 2013-02-12 07:28:48 | [diff] [blame] | 104 | var maxLen = -Infinity; |
| 105 | var util = require('util'); |
isaacs | 087c437 | 2013-02-13 18:47:29 | [diff] [blame] | 106 | console.log(start); |
| 107 | |
isaacs | aa2edd4 | 2013-02-12 07:28:48 | [diff] [blame] | 108 | Object.keys(results).map(function(bench) { |
| 109 | var res = results[bench]; |
| 110 | var n0 = res[nodes[0]]; |
| 111 | var n1 = res[nodes[1]]; |
| 112 | |
isaacs | 035aa6b | 2013-02-13 18:48:55 | [diff] [blame] | 113 | var pct = ((n0 - n1) / n1 * 100).toFixed(2); |
isaacs | aa2edd4 | 2013-02-12 07:28:48 | [diff] [blame] | 114 | |
| 115 | var g = n0 > n1 ? green : ''; |
| 116 | var r = n0 > n1 ? '' : red; |
| 117 | var c = r || g; |
| 118 | |
| 119 | if (show === 'green' && !g || show === 'red' && !r) |
| 120 | return; |
| 121 | |
| 122 | var r0 = util.format('%s%s: %d%s', g, nodes[0], n0, reset); |
| 123 | var r1 = util.format('%s%s: %d%s', r, nodes[1], n1, reset); |
| 124 | var pct = c + pct + '%' + reset; |
| 125 | var l = util.format('%s: %s %s', bench, r0, r1); |
| 126 | maxLen = Math.max(l.length + pct.length, maxLen); |
| 127 | return [l, pct]; |
| 128 | }).filter(function(l) { |
| 129 | return l; |
| 130 | }).forEach(function(line) { |
| 131 | var l = line[0]; |
| 132 | var pct = line[1]; |
| 133 | var dotLen = maxLen - l.length - pct.length + 2; |
| 134 | var dots = ' ' + new Array(Math.max(0, dotLen)).join('.') + ' '; |
| 135 | console.log(l + dots + pct); |
| 136 | }); |
isaacs | 087c437 | 2013-02-13 18:47:29 | [diff] [blame] | 137 | console.log(end); |
isaacs | aa2edd4 | 2013-02-12 07:28:48 | [diff] [blame] | 138 | } |