Skip to content

Commit 1e05ddf

Browse files
mscdexMylesBorins
authored andcommitted
stream: improve writable.write() performance
Backport-PR-URL: #32169 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>
1 parent 90a4d43 commit 1e05ddf

1 file changed

Lines changed: 27 additions & 48 deletions

File tree

‎lib/_stream_writable.js‎

Lines changed: 27 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -268,35 +268,8 @@ Writable.prototype.pipe = function() {
268268
};
269269

270270

271-
functionwriteAfterEnd(stream,cb){
272-
conster=newERR_STREAM_WRITE_AFTER_END();
273-
// TODO: defer error events consistently everywhere, not just the cb
274-
errorOrDestroy(stream,er);
275-
process.nextTick(cb,er);
276-
}
277-
278-
// Checks that a user-supplied chunk is valid, especially for the particular
279-
// mode the stream is in. Currently this means that `null` is never accepted
280-
// and undefined/non-string values are only allowed in object mode.
281-
functionvalidChunk(stream,state,chunk,cb){
282-
varer;
283-
284-
if(chunk===null){
285-
er=newERR_STREAM_NULL_VALUES();
286-
}elseif(typeofchunk!=='string'&&!state.objectMode){
287-
er=newERR_INVALID_ARG_TYPE('chunk',['string','Buffer'],chunk);
288-
}
289-
if(er){
290-
errorOrDestroy(stream,er);
291-
process.nextTick(cb,er);
292-
returnfalse;
293-
}
294-
returntrue;
295-
}
296-
297271
Writable.prototype.write=function(chunk,encoding,cb){
298272
conststate=this._writableState;
299-
varret=false;
300273
constisBuf=!state.objectMode&&Stream._isUint8Array(chunk);
301274

302275
// Do not use Object.getPrototypeOf as it is slower since V8 7.3.
@@ -306,29 +279,42 @@ Writable.prototype.write = function(chunk, encoding, cb) {
306279

307280
if(typeofencoding==='function'){
308281
cb=encoding;
309-
encoding=null;
282+
encoding=state.defaultEncoding;
283+
}else{
284+
if(!encoding)
285+
encoding=state.defaultEncoding;
286+
if(typeofcb!=='function')
287+
cb=nop;
310288
}
311289

312290
if(isBuf)
313291
encoding='buffer';
314-
elseif(!encoding)
315-
encoding=state.defaultEncoding;
316-
317-
if(typeofcb!=='function')
318-
cb=nop;
319292

293+
leterr;
320294
if(state.ending){
321-
writeAfterEnd(this,cb);
295+
err=newERR_STREAM_WRITE_AFTER_END();
322296
}elseif(state.destroyed){
323-
consterr=newERR_STREAM_DESTROYED('write');
324-
process.nextTick(cb,err);
325-
errorOrDestroy(this,err);
326-
}elseif(isBuf||validChunk(this,state,chunk,cb)){
327-
state.pendingcb++;
328-
ret=writeOrBuffer(this,state,chunk,encoding,cb);
297+
err=newERR_STREAM_DESTROYED('write');
298+
}elseif(chunk===null){
299+
err=newERR_STREAM_NULL_VALUES();
300+
}else{
301+
if(!isBuf&&!state.objectMode){
302+
if(typeofchunk!=='string'){
303+
err=newERR_INVALID_ARG_TYPE('chunk',['string','Buffer'],chunk);
304+
}elseif(encoding!=='buffer'&&state.decodeStrings!==false){
305+
chunk=Buffer.from(chunk,encoding);
306+
encoding='buffer';
307+
}
308+
}
309+
if(err===undefined){
310+
state.pendingcb++;
311+
returnwriteOrBuffer(this,state,chunk,encoding,cb);
312+
}
329313
}
330314

331-
returnret;
315+
process.nextTick(cb,err);
316+
errorOrDestroy(this,err,true);
317+
returnfalse;
332318
};
333319

334320
Writable.prototype.cork=function(){
@@ -363,13 +349,6 @@ Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
363349
// in the queue, and wait our turn. Otherwise, call _write
364350
// If we return false, then we need a drain event, so set that flag.
365351
functionwriteOrBuffer(stream,state,chunk,encoding,cb){
366-
if(!state.objectMode&&
367-
state.decodeStrings!==false&&
368-
encoding!=='buffer'&&
369-
typeofchunk==='string'){
370-
chunk=Buffer.from(chunk,encoding);
371-
encoding='buffer';
372-
}
373352
constlen=state.objectMode ? 1 : chunk.length;
374353

375354
state.length+=len;

0 commit comments

Comments
 (0)