summaryrefslogtreecommitdiff
path: root/benchmark/fs-write-stream-throughput.js
blob: f1c8d3cc1a6d168cddea1e570a27b11330605c44 (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
87
88
89
90
91
92
93
94
95
// If there are no args, then this is the root.  Run all the benchmarks!
'use strict';
if (!process.argv[2])
  parent();
else
  runTest(+process.argv[2], +process.argv[3], process.argv[4]);

function parent() {
  var types = [ 'string', 'buffer' ];
  var durs = [ 1, 5 ];
  var sizes = [ 1, 10, 100, 2048, 10240 ];
  var queue = [];
  types.forEach(function(t) {
    durs.forEach(function(d) {
      sizes.forEach(function(s) {
        queue.push([__filename, d, s, t]);
      });
    });
  });

  var spawn = require('child_process').spawn;
  var node = process.execPath;

  run();

  function run() {
    var args = queue.shift();
    if (!args)
      return;
    var child = spawn(node, args, { stdio: 'inherit' });
    child.on('close', function(code, signal) {
      if (code)
        throw new Error('Benchmark failed: ' + args.slice(1));
      run();
    });
  }
}

function runTest(dur, size, type) {
  if (type !== 'string')
    type = 'buffer';
  var chunk;
  switch (type) {
    case 'string':
      chunk = new Array(size + 1).join('a');
      break;
    case 'buffer':
      chunk = Buffer.alloc(size, 'a');
      break;
  }

  var fs = require('fs');
  try { fs.unlinkSync('write_stream_throughput'); } catch (e) {}

  var start;
  var end;
  function done() {
    var time = end[0] + end[1] / 1E9;
    var written = fs.statSync('write_stream_throughput').size / 1024;
    var rate = (written / time).toFixed(2);
    console.log('fs_write_stream_dur_%d_size_%d_type_%s: %d',
                dur, size, type, rate);

    try { fs.unlinkSync('write_stream_throughput'); } catch (e) {}
  }

  var f = require('fs').createWriteStream('write_stream_throughput');
  f.on('drain', write);
  f.on('open', write);
  f.on('close', done);

  // streams2 fs.WriteStreams will let you send a lot of writes into the
  // buffer before returning false, so capture the *actual* end time when
  // all the bytes have been written to the disk, indicated by 'finish'
  f.on('finish', function() {
    end = process.hrtime(start);
  });

  var ending = false;
  function write() {
    // don't try to write after we end, even if a 'drain' event comes.
    // v0.8 streams are so sloppy!
    if (ending)
      return;

    start = start || process.hrtime();
    while (false !== f.write(chunk));
    end = process.hrtime(start);

    if (end[0] >= dur) {
      ending = true;
      f.end();
    }
  }
}