stream: improve stream creation performance
PR-URL: https://github.com/nodejs/node/pull/19401 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Minwoo Jung <minwoo@nodesource.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
This commit is contained in:
parent
1c8149417a
commit
b41ed29b80
55
benchmark/streams/creation.js
Normal file
55
benchmark/streams/creation.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
'use strict';
|
||||||
|
const common = require('../common.js');
|
||||||
|
const Duplex = require('stream').Duplex;
|
||||||
|
const Readable = require('stream').Readable;
|
||||||
|
const Transform = require('stream').Transform;
|
||||||
|
const Writable = require('stream').Writable;
|
||||||
|
|
||||||
|
const bench = common.createBenchmark(main, {
|
||||||
|
n: [50e6],
|
||||||
|
kind: ['duplex', 'readable', 'transform', 'writable']
|
||||||
|
});
|
||||||
|
|
||||||
|
function main({ n, kind }) {
|
||||||
|
var i = 0;
|
||||||
|
switch (kind) {
|
||||||
|
case 'duplex':
|
||||||
|
new Duplex({});
|
||||||
|
new Duplex();
|
||||||
|
|
||||||
|
bench.start();
|
||||||
|
for (; i < n; ++i)
|
||||||
|
new Duplex();
|
||||||
|
bench.end(n);
|
||||||
|
break;
|
||||||
|
case 'readable':
|
||||||
|
new Readable({});
|
||||||
|
new Readable();
|
||||||
|
|
||||||
|
bench.start();
|
||||||
|
for (; i < n; ++i)
|
||||||
|
new Readable();
|
||||||
|
bench.end(n);
|
||||||
|
break;
|
||||||
|
case 'writable':
|
||||||
|
new Writable({});
|
||||||
|
new Writable();
|
||||||
|
|
||||||
|
bench.start();
|
||||||
|
for (; i < n; ++i)
|
||||||
|
new Writable();
|
||||||
|
bench.end(n);
|
||||||
|
break;
|
||||||
|
case 'transform':
|
||||||
|
new Transform({});
|
||||||
|
new Transform();
|
||||||
|
|
||||||
|
bench.start();
|
||||||
|
for (; i < n; ++i)
|
||||||
|
new Transform();
|
||||||
|
bench.end(n);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Invalid kind');
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
const common = require('../common.js');
|
|
||||||
const Transform = require('stream').Transform;
|
|
||||||
const inherits = require('util').inherits;
|
|
||||||
|
|
||||||
const bench = common.createBenchmark(main, {
|
|
||||||
n: [1e6]
|
|
||||||
});
|
|
||||||
|
|
||||||
function MyTransform() {
|
|
||||||
Transform.call(this);
|
|
||||||
}
|
|
||||||
inherits(MyTransform, Transform);
|
|
||||||
MyTransform.prototype._transform = function() {};
|
|
||||||
|
|
||||||
function main({ n }) {
|
|
||||||
bench.start();
|
|
||||||
for (var i = 0; i < n; ++i)
|
|
||||||
new MyTransform();
|
|
||||||
bench.end(n);
|
|
||||||
}
|
|
@ -64,7 +64,7 @@ function prependListener(emitter, event, fn) {
|
|||||||
emitter._events[event] = [fn, emitter._events[event]];
|
emitter._events[event] = [fn, emitter._events[event]];
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReadableState(options, stream) {
|
function ReadableState(options, stream, isDuplex) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
// Duplex streams are both readable and writable, but share
|
// Duplex streams are both readable and writable, but share
|
||||||
@ -72,7 +72,8 @@ function ReadableState(options, stream) {
|
|||||||
// However, some cases require setting options to different
|
// However, some cases require setting options to different
|
||||||
// values for the readable and the writable sides of the duplex stream.
|
// values for the readable and the writable sides of the duplex stream.
|
||||||
// These options can be provided separately as readableXXX and writableXXX.
|
// These options can be provided separately as readableXXX and writableXXX.
|
||||||
var isDuplex = stream instanceof Stream.Duplex;
|
if (typeof isDuplex !== 'boolean')
|
||||||
|
isDuplex = stream instanceof Stream.Duplex;
|
||||||
|
|
||||||
// object stream flag. Used to make read(n) ignore n and to
|
// object stream flag. Used to make read(n) ignore n and to
|
||||||
// make all the buffer merging and length checks go away
|
// make all the buffer merging and length checks go away
|
||||||
@ -142,7 +143,11 @@ function Readable(options) {
|
|||||||
if (!(this instanceof Readable))
|
if (!(this instanceof Readable))
|
||||||
return new Readable(options);
|
return new Readable(options);
|
||||||
|
|
||||||
this._readableState = new ReadableState(options, this);
|
// Checking for a Stream.Duplex instance is faster here instead of inside
|
||||||
|
// the ReadableState constructor, at least with V8 6.5
|
||||||
|
const isDuplex = (this instanceof Stream.Duplex);
|
||||||
|
|
||||||
|
this._readableState = new ReadableState(options, this, isDuplex);
|
||||||
|
|
||||||
// legacy
|
// legacy
|
||||||
this.readable = true;
|
this.readable = true;
|
||||||
|
@ -48,7 +48,7 @@ util.inherits(Writable, Stream);
|
|||||||
|
|
||||||
function nop() {}
|
function nop() {}
|
||||||
|
|
||||||
function WritableState(options, stream) {
|
function WritableState(options, stream, isDuplex) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
// Duplex streams are both readable and writable, but share
|
// Duplex streams are both readable and writable, but share
|
||||||
@ -56,7 +56,8 @@ function WritableState(options, stream) {
|
|||||||
// However, some cases require setting options to different
|
// However, some cases require setting options to different
|
||||||
// values for the readable and the writable sides of the duplex stream.
|
// values for the readable and the writable sides of the duplex stream.
|
||||||
// These options can be provided separately as readableXXX and writableXXX.
|
// These options can be provided separately as readableXXX and writableXXX.
|
||||||
var isDuplex = stream instanceof Stream.Duplex;
|
if (typeof isDuplex !== 'boolean')
|
||||||
|
isDuplex = stream instanceof Stream.Duplex;
|
||||||
|
|
||||||
// object stream flag to indicate whether or not this stream
|
// object stream flag to indicate whether or not this stream
|
||||||
// contains buffers or objects.
|
// contains buffers or objects.
|
||||||
@ -201,12 +202,15 @@ function Writable(options) {
|
|||||||
// Trying to use the custom `instanceof` for Writable here will also break the
|
// Trying to use the custom `instanceof` for Writable here will also break the
|
||||||
// Node.js LazyTransform implementation, which has a non-trivial getter for
|
// Node.js LazyTransform implementation, which has a non-trivial getter for
|
||||||
// `_writableState` that would lead to infinite recursion.
|
// `_writableState` that would lead to infinite recursion.
|
||||||
if (!(realHasInstance.call(Writable, this)) &&
|
|
||||||
!(this instanceof Stream.Duplex)) {
|
|
||||||
return new Writable(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._writableState = new WritableState(options, this);
|
// Checking for a Stream.Duplex instance is faster here instead of inside
|
||||||
|
// the WritableState constructor, at least with V8 6.5
|
||||||
|
const isDuplex = (this instanceof Stream.Duplex);
|
||||||
|
|
||||||
|
if (!isDuplex && !realHasInstance.call(Writable, this))
|
||||||
|
return new Writable(options);
|
||||||
|
|
||||||
|
this._writableState = new WritableState(options, this, isDuplex);
|
||||||
|
|
||||||
// legacy.
|
// legacy.
|
||||||
this.writable = true;
|
this.writable = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user