Skip to content

Faster Transform stream #33397

Description

@ronag

Some thoughts on how to make Transform streams faster.

Part of the overhead of Transform (and PassThrough) is that it is actually 2 streams, one Writable and one Readable, both with buffering and state management, which are connected together.

We could try to skip this and implement Transform as a Readable which implements the Writable interface and proxies the naming.

e.g.

classFastTransformextendsReadable{constructor(options){super(options)this._writableState={length: 0,needDrain: false,ended: false,finished: false}}getwritableEnded(){returnthis._writableState.ended}getwritableFinished(){returnthis._writableState.finished}_read(){constrState=this._readableStateconstwState=this._writableStateif(!wState.needDrain){return}if(wState.length+rState.length>rState.highWaterMark){return}wState.needDrain=falsethis.emit('drain')}write(chunk){constrState=this._readableStateconstwState=this._writableStateconstlen=chunk.lengthwState.length+=lenthis._transform(chunk,null,(err,data)=>{wState.length-=lenif(err){this.destroy(err)}elseif(data!=null){this.push(data)}this._read()})wState.needDrain=wState.length+rState.length>rState.highWaterMarkreturnwState.needDrain}end(){constwState=this._writableStatewState.ended=trueif(this._flush){this._flush(chunk,(err,data)=>{constwState=this._writableStateif(err){this.destroy(err)}else{if(data!=null){this.push(data)}this.push(null)wState.finished=truethis.emit('finish')}})}else{this.push(null)wState.finished=truethis.emit('finish')}}}// TODO: Make Writable[Symbol.hasInstance] recognize `FastTransform`.

Making this fully backwards compatible with Transform might be difficult.

Metadata

Metadata

Assignees

Labels

streamIssues and PRs related to the stream subsystem.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions