如何对Node.js流进行基准测试? [英] How to benchmark Node.js streams?
问题描述
如何在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 :
- 使用基准的延迟选项 benchmarkjs文档
- 确保管道操作何时结束 node.js文档
- 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屋!