From 43783b5b3fa0a0d477ae34aeb0405956fb534dc4 Mon Sep 17 00:00:00 2001 From: Brian White Date: Mon, 3 Feb 2020 16:18:57 -0500 Subject: [PATCH] stream: improve writable.write() performance PR-URL: https://github.com/nodejs/node/pull/31624 Reviewed-By: Matteo Collina Reviewed-By: James M Snell Reviewed-By: Luigi Pinca --- lib/_stream_writable.js | 45 +++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index c42760c2b25e63..9c38da3f107ba0 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -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. @@ -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) { @@ -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() { @@ -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;