joyent/node — pull request #4911 by isaacs (2013-03-04 06:06:09+00:00)
Title: Stream writable refactor

This is still a bit of a wip branch, and ought to be squashed somewhat before being merged. But the results are promising.

Semantic changes to the stream2 API:

1. `Writable.prototype._write` now takes 3 arguments, always: `chunk, encoding, cb`. If you have not set `decodeStrings: false` in the options, then the first argument will always be a Buffer. If you have, then it'll be whatever the user provided.
2. `Transform.prototype._transform` does not get an `output` function. Instead, it also receives `chunk, encoding, cb`, and the user needs to call `stream.push(chunk)` to provide output, just like with Readable streams.

These are both breaking changes to Streams2 up until this point. @TooTallNate: Please provide feedback.

Cosmetic changes:

1. The `write` and `onwrite` functions in `_stream_writable.js` are completely split up into small methods that do not return early, and get called with consistent argument types (except for the String/Buffer disparity in `_write`, but that can't be helped.)
2. If the user calls `stream.write(chunk)` while a write is already in progress, then the entry in the buffer is a `WriteReq` object, instead of an array.

The performance effect is promising. I'm seeing about a 6% increase on benchmark/http.sh, and a [lot of green](http://static.izs.me/benchmark-write-refactor-vs-0.8.html) on bench-http, testing against the latest v0.8 branch.

I suspect that more gains could be had by similarly organizing and optimizing the code paths in Socket.write and Readable.read.