Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f928746

Browse filesBrowse files
mscdexMylesBorins
authored andcommitted
stream: avoid additional validation for Buffers
These changes result in ~50% improvement in the included benchmark. PR-URL: #10580 Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent de22ff6 commit f928746
Copy full SHA for f928746

File tree

Expand file treeCollapse file tree

2 files changed

+40
-20
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+40
-20
lines changed
Open diff view settings
Collapse file
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const Writable = require('stream').Writable;
5+
6+
const bench = common.createBenchmark(main, {
7+
n: [2e6]
8+
});
9+
10+
function main(conf) {
11+
const n = +conf.n;
12+
const b = Buffer.allocUnsafe(1024);
13+
const s = new Writable();
14+
s._write = function(chunk, encoding, cb) {
15+
cb();
16+
};
17+
18+
bench.start();
19+
for (var k = 0; k < n; ++k) {
20+
s.write(b);
21+
}
22+
bench.end(n);
23+
}
Collapse file

‎lib/_stream_writable.js‎

Copy file name to clipboardExpand all lines: lib/_stream_writable.js
+17-20Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -196,23 +196,18 @@ function writeAfterEnd(stream, cb) {
196196
process.nextTick(cb, er);
197197
}
198198

199-
// If we get something that is not a buffer, string, null, or undefined,
200-
// and we're not in objectMode, then that's an error.
201-
// Otherwise stream chunks are all considered to be of length=1, and the
202-
// watermarks determine how many objects to keep in the buffer, rather than
203-
// how many bytes or characters.
199+
// Checks that a user-supplied chunk is valid, especially for the particular
200+
// mode the stream is in. Currently this means that `null` is never accepted
201+
// and undefined/non-string values are only allowed in object mode.
204202
function validChunk(stream, state, chunk, cb) {
205203
var valid = true;
206204
var er = false;
207-
// Always throw error if a null is written
208-
// if we are not in object mode then throw
209-
// if it is not a buffer, string, or undefined.
205+
210206
if (chunk === null) {
211207
er = new TypeError('May not write null values to stream');
212-
} else if (!(chunk instanceof Buffer) &&
213-
typeof chunk !== 'string' &&
214-
chunk !== undefined &&
215-
!state.objectMode) {
208+
} else if (typeof chunk !== 'string' &&
209+
chunk !== undefined &&
210+
!state.objectMode) {
216211
er = new TypeError('Invalid non-string/buffer chunk');
217212
}
218213
if (er) {
@@ -226,13 +221,14 @@ function validChunk(stream, state, chunk, cb) {
226221
Writable.prototype.write = function(chunk, encoding, cb) {
227222
var state = this._writableState;
228223
var ret = false;
224+
var isBuf = (chunk instanceof Buffer);
229225

230226
if (typeof encoding === 'function') {
231227
cb = encoding;
232228
encoding = null;
233229
}
234230

235-
if (chunk instanceof Buffer)
231+
if (isBuf)
236232
encoding = 'buffer';
237233
else if (!encoding)
238234
encoding = state.defaultEncoding;
@@ -242,9 +238,9 @@ Writable.prototype.write = function(chunk, encoding, cb) {
242238

243239
if (state.ended)
244240
writeAfterEnd(this, cb);
245-
else if (validChunk(this, state, chunk, cb)) {
241+
else if (isBuf || validChunk(this, state, chunk, cb)) {
246242
state.pendingcb++;
247-
ret = writeOrBuffer(this, state, chunk, encoding, cb);
243+
ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
248244
}
249245

250246
return ret;
@@ -293,11 +289,12 @@ function decodeChunk(state, chunk, encoding) {
293289
// if we're already writing something, then just put this
294290
// in the queue, and wait our turn. Otherwise, call _write
295291
// If we return false, then we need a drain event, so set that flag.
296-
function writeOrBuffer(stream, state, chunk, encoding, cb) {
297-
chunk = decodeChunk(state, chunk, encoding);
298-
299-
if (chunk instanceof Buffer)
300-
encoding = 'buffer';
292+
function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
293+
if (!isBuf) {
294+
chunk = decodeChunk(state, chunk, encoding);
295+
if (chunk instanceof Buffer)
296+
encoding = 'buffer';
297+
}
301298
var len = state.objectMode ? 1 : chunk.length;
302299

303300
state.length += len;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.