如何基准Node.jsstream?

如何在Node.js中对stream进行基准testing?

我试过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 

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

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

这是由于stream是asynchronous的,在结束时没有明确的callback。 所以你几乎在in.txt和out.txt之间创build了成千上万的pipe道stream,直到系统告诉你他们打开了太多的文件描述符。

因此,我猜测通过“在Node中对基准stream进行基准testing”,您想要计算的是同步执行此操作所需的时间:

 reader.pipe(filter).pipe(writer) 

在这种情况下,您将需要:

  • 使用基准benchmarkjs文档的推迟选项
  • 请确保pipe道操作在node.js文档上

这个答案的代码已经在节点0.10.0进行了testing,但我想唯一的区别应该在模块的名称保存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();