如何对Node.js流进行基准测试? [英] How to benchmark Node.js streams?

查看:106
本文介绍了如何对Node.js流进行基准测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I benchmark streams in 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


推荐答案

你的代码遇到这个错误,你可以通过听读者和作者的错误看到它:

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'

这是因为流是异步的而没有显式回调什么时候结束所以你几乎在in.txt和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.

所以,我想通过在Node中对流进行基准测试,您想要计算的是同步执行此操作所需的时间:

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 :

reader.pipe(filter).pipe(writer)

在这种情况下你将需要:

In that case you will need to :

  • use the defer option of benchmark benchmarkjs documentation
  • be sure when pipe operation is over node.js documentation

此答案的代码已使用节点0.10.0进行测试,但我想唯一的区别应该是模块名称中包含 Transform

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 :

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();

这篇关于如何对Node.js流进行基准测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆