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 59196af

Browse filesBrowse files
mscdexItalo A. Casas
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 ded1757 commit 59196af
Copy full SHA for 59196af

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
@@ -194,23 +194,18 @@ function writeAfterEnd(stream, cb) {
194194
process.nextTick(cb, er);
195195
}
196196

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

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

233-
if (chunk instanceof Buffer)
229+
if (isBuf)
234230
encoding = 'buffer';
235231
else if (!encoding)
236232
encoding = state.defaultEncoding;
@@ -240,9 +236,9 @@ Writable.prototype.write = function(chunk, encoding, cb) {
240236

241237
if (state.ended)
242238
writeAfterEnd(this, cb);
243-
else if (validChunk(this, state, chunk, cb)) {
239+
else if (isBuf || validChunk(this, state, chunk, cb)) {
244240
state.pendingcb++;
245-
ret = writeOrBuffer(this, state, chunk, encoding, cb);
241+
ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
246242
}
247243

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

301298
state.length += len;

0 commit comments

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