4

Node.jsでストリームをベンチマークするにはどうすればよいですか?

私はbenchmark.jsを試しました:

var fs = require('fs');
var Transform = require('readable-stream').Transform;
var util = require('util');
var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;

// my super uppercase stream
function Uppercase(options) {
  if (!(this instanceof Uppercase))
    return new Uppercase(options);

  Transform.call(this, options);
}

Uppercase.prototype = Object.create(
  Transform.prototype, { constructor: { value: Uppercase }});

Uppercase.prototype._transform = function(chunk, encoding, done) {
  chunk = chunk.toString().toUpperCase();
  this.push(chunk)
};

// start benchmarking
suite.add('stream test', function() {
  var reader = fs.createReadStream('in.txt');
  var parser = new Uppercase();
  var writer = fs.createWriteStream('out.txt');
  reader.pipe(parser).pipe(writer);
})
// add listeners
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
// run async
.run();

suite.run();

しかし、私はエラーを受け取ります

Unhandled stream error in pipe
4

1 に答える 1

3

あなたのコードはこのエラーに遭遇します、あなたはリーダーとライターのエラーを聞くことによってそれを見ることができます:

[Error: EMFILE, open 'out.txt'] errno: 20, code: 'EMFILE', path: 'in.txt'
[Error: EMFILE, open 'out.txt'] errno: 20, code: 'EMFILE', path: 'out.txt'

これは、ストリームが非同期であり、終了時に明示的なコールバックがないために発生します。したがって、システムが開いているファイル記述子が多すぎると通知するまで、in.txtとout.txtの間に何千ものパイプストリームを作成していることになります。

したがって、「ノードでストリームをベンチマークする」ことによって、計算したいのは、この操作を同期的に実行するのにかかる時間だと思います。

reader.pipe(filter).pipe(writer)

その場合、次のことを行う必要があります。

この回答のコードはノード0.10.0でテストされていますが、唯一の違いは、以下を保持するモジュールの名前にあるはずですTransform

var fs = require('fs');
var util = require('util');
var Transform = require('stream').Transform;
var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;

var i = 0;

// my super uppercase stream
function Uppercase(options) {
  if (!(this instanceof Uppercase))
    return new Uppercase(options);

  Transform.call(this, options);
}

Uppercase.prototype = Object.create(
  Transform.prototype, { constructor: { value: Uppercase }}
);

Uppercase.prototype._transform = function(chunk, encoding, done) {
  chunk = chunk.toString().toUpperCase();
  this.push(chunk)
};



// start benchmarking
suite.add('stream test', {
  'defer' : true,
  'fn' : function (deferred) {
    var reader = fs.createReadStream('in.txt');
    var parser = new Uppercase();
    var writer = fs.createWriteStream('out.txt');

    reader.on('error', function (err) {
      console.log(err);
    });
    writer.on('error', function (err) {
      console.log(err);
    });
    reader.on('end', function  (argument) {
      // Wait until reader is over and then close reader and finish deferred test
      writer.end();
      deferred.resolve();
    });

    reader.pipe(parser).pipe(writer, {'end': false});
  }
})

//  listeners
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})

// run async
.run();
于 2013-03-20T11:09:28.723 に答える