summaryrefslogtreecommitdiff
path: root/benchmark/compare.js
blob: 94ff19bb56701a9cd968340e10d85d198a9a09d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
'use strict';

const fork = require('child_process').fork;
const path = require('path');
const CLI = require('./_cli.js');

//
// Parse arguments
//
const cli = CLI(`usage: ./node compare.js [options] [--] <category> ...
  Run each benchmark in the <category> directory many times using two diffrent
  node versions. More than one <category> directory can be specified.
  The output is formatted as csv, which can be processed using for
  example 'compare.R'.

  --new    ./new-node-binary  new node binary (required)
  --old    ./old-node-binary  old node binary (required)
  --runs   30                 number of samples
  --filter pattern            string to filter benchmark scripts
  --set    variable=value     set benchmark variable (can be repeated)
`, {
  arrayArgs: ['set']
});

if (!cli.optional.new || !cli.optional.old) {
  cli.abort(cli.usage);
  return;
}

const binaries = ['old', 'new'];
const runs = cli.optional.runs ? parseInt(cli.optional.runs, 10) : 30;
const benchmarks = cli.benchmarks();

if (benchmarks.length === 0) {
  console.error('no benchmarks found');
  process.exit(1);
}

// Create queue from the benchmarks list such both node versions are tested
// `runs` amount of times each.
const queue = [];
for (let iter = 0; iter < runs; iter++) {
  for (const filename of benchmarks) {
    for (const binary of binaries) {
      queue.push({ binary, filename, iter });
    }
  }
}

// Print csv header
console.log('"binary", "filename", "configuration", "rate", "time"');

(function recursive(i) {
  const job = queue[i];

  const child = fork(path.resolve(__dirname, job.filename), cli.optional.set, {
    execPath: cli.optional[job.binary]
  });

  child.on('message', function(data) {
    // Construct configuration string, " A=a, B=b, ..."
    let conf = '';
    for (const key of Object.keys(data.conf)) {
      conf += ' ' + key + '=' + JSON.stringify(data.conf[key]);
    }
    conf = conf.slice(1);

    // Escape quotes (") for correct csv formatting
    conf = conf.replace(/"/g, '""');

    console.log(`"${job.binary}", "${job.filename}", "${conf}", ` +
                `${data.rate}, ${data.time}`);
  });

  child.once('close', function(code) {
    if (code) {
      process.exit(code);
      return;
    }

    // If there are more benchmarks execute the next
    if (i + 1 < queue.length) {
      recursive(i + 1);
    }
  });
})(0);