Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
stream: improve writable.write() performance
PR-URL: #31624
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
  • Loading branch information
mscdex committed Feb 9, 2020
commit 43783b5b3fa0a0d477ae34aeb0405956fb534dc4
45 changes: 21 additions & 24 deletions lib/_stream_writable.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ Writable.prototype.pipe = function() {

Writable.prototype.write = function(chunk, encoding, cb) {
const state = this._writableState;
var ret = false;
const isBuf = !state.objectMode && Stream._isUint8Array(chunk);

// Do not use Object.getPrototypeOf as it is slower since V8 7.3.
Expand All @@ -271,16 +270,16 @@ Writable.prototype.write = function(chunk, encoding, cb) {

if (typeof encoding === 'function') {
cb = encoding;
encoding = null;
encoding = state.defaultEncoding;
} else {
if (!encoding)
encoding = state.defaultEncoding;
if (typeof cb !== 'function')
cb = nop;
}

if (isBuf)
encoding = 'buffer';
else if (!encoding)
encoding = state.defaultEncoding;

if (typeof cb !== 'function')
cb = nop;

let err;
if (state.ending) {
Expand All @@ -289,19 +288,24 @@ Writable.prototype.write = function(chunk, encoding, cb) {
err = new ERR_STREAM_DESTROYED('write');
} else if (chunk === null) {
err = new ERR_STREAM_NULL_VALUES();
} else if (!isBuf && typeof chunk !== 'string' && !state.objectMode) {
err = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
} else {
state.pendingcb++;
ret = writeOrBuffer(this, state, chunk, encoding, cb);
}

if (err) {
process.nextTick(cb, err);
errorOrDestroy(this, err, true);
if (!isBuf && !state.objectMode) {
if (typeof chunk !== 'string') {
err = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
} else if (encoding !== 'buffer' && state.decodeStrings !== false) {
chunk = Buffer.from(chunk, encoding);
encoding = 'buffer';
}
}
if (err === undefined) {
state.pendingcb++;
return writeOrBuffer(this, state, chunk, encoding, cb);
}
}

return ret;
process.nextTick(cb, err);
errorOrDestroy(this, err, true);
return false;
};

Writable.prototype.cork = function() {
Expand Down Expand Up @@ -376,13 +380,6 @@ ObjectDefineProperty(Writable.prototype, 'writableCorked', {
// in the queue, and wait our turn. Otherwise, call _write
// If we return false, then we need a drain event, so set that flag.
function writeOrBuffer(stream, state, chunk, encoding, cb) {
if (!state.objectMode &&
state.decodeStrings !== false &&
encoding !== 'buffer' &&
typeof chunk === 'string') {
chunk = Buffer.from(chunk, encoding);
encoding = 'buffer';
}
const len = state.objectMode ? 1 : chunk.length;

state.length += len;
Expand Down