简体   繁体   English

如何对Node.js流进行基准测试?

[英]How to benchmark Node.js streams?

How can I benchmark streams in Node.js? 我怎样才能标杆中的Node.js?

I've tried benchmark.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();

But I get the error 但是我得到了错误

Unhandled stream error in pipe

Your code encounter this error, you could see it by listen to error on reader and writer : 你的代码遇到这个错误,你可以通过听读者和作者的错误看到它:

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

This is caused by the fact that streams are asynchronous and without explicit callback on when they end. 这是因为流是异步的,并且在它们结束时没有显式回调。 So you are pretty much creating thousand and thousands of pipe stream between in.txt and out.txt untill the system tells you they are too many files descriptor open. 所以你几乎在in.txt和out.txt之间创建了成千上万的管道流,直到系统告诉你它们是太多的文件描述符打开。

So, I'll guess that by "benchmarking streams in Node", what you want to want to calculate is the time it takes to do synchronously perform this operation : 所以,我猜想通过“在Node中对流进行基准测试”,您想要计算的是同步执行此操作所需的时间:

reader.pipe(filter).pipe(writer)

In that case you will need to : 在这种情况下,您需要:

The code for this answer has been tested with node 0.10.0, but I guess that the only difference should be in the name of the module which holds Transform : 这个答案的代码已经使用节点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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM