stream: improve Readable.read() performance#7077
Conversation
|
/cc @nodejs/streams |
|
should buffer list maybe live in the internals folder ? |
|
@calvinmetcalf Debatable but I left it there since it's only used by Readable and it's better if Readable isn't referencing anything from |
|
I can extract that other file easily, I'm more worried about exporting that from readable which is not on the api |
|
@calvinmetcalf I don't understand what you mean by "is not on the api." |
|
sorry, misspoke, I meant that I didn't like exporting that new thing from readable |
|
@calvinmetcalf I can remove it if necessary I suppose, but then we'd end up duplicating some of it in the tests I had to modify. I thought it would be better not to have to keep two separate "implementations" in sync. |
|
I was thinking that if that file got moved to something in internal, then you could just require that for the tests and require it for from stream_readable and don't worry about the readable-stream module, it won't be much of an inconvenience. |
e90c652 to
1ae67c9
Compare
|
@calvinmetcalf Ok, moved to internal. |
1ae67c9 to
47d6cc0
Compare
lib/internal/streams/BufferList.js
Outdated
There was a problem hiding this comment.
Do you think it could help to create an Entry class to increase property access performance?
There was a problem hiding this comment.
I just tried it and it doesn't seem to make any real difference. If anything it seems to slow things down a little bit.
|
/cc @nodejs/collaborators Anyone have any comments/questions/LGTMs on this? |
lib/_stream_readable.js
Outdated
There was a problem hiding this comment.
I'm not sure on the style guide on this, but the outer braces seem useless.
There was a problem hiding this comment.
You mean the parens? shrug I always add that when "assigning" a ternary statement to a variable as it seems more readable/clear to me.
There was a problem hiding this comment.
I noticed :) I don't really mind, just curious if there's any consensus on this. No blocker, no worries.
And sorry, yeah, parens (I, non-native English speaker, always get these mixed up... sigh)
f1922f1 to
1f2fbc2
Compare
1f2fbc2 to
729b645
Compare
|
First read through looks good but I'll have to go through in more detail tomorrow. In general tho, if @nodejs/streams is happy, then ++ |
|
Do we have a CITGM run? If that passes.. LGTM. just with one catch.. Let's give this a long time before we backport. |
|
the job was aborted, should we kick it off again? |
|
@mcollina It was aborted most likely because the ppcle machine is/was still down. The lodash failure on OSX1010 looks like an npm or citgm failure since it failed on installation of the package. Otherwise citgm is green. |
|
LGTM as semver-minor. |
read() performance is improved most by switching from an array to a linked list for storing buffered data. However, other changes that also contribute include: making some hot functions inlinable, faster read() argument checking, and misc code rearrangement to avoid unnecessary code execution. PR-URL: #7077 Reviewed-By: Calvin Metcalf <calvin.metcalf@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
read() performance is improved most by switching from an array to a linked list for storing buffered data. However, other changes that also contribute include: making some hot functions inlinable, faster read() argument checking, and misc code rearrangement to avoid unnecessary code execution. PR-URL: #7077 Reviewed-By: Calvin Metcalf <calvin.metcalf@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
@mcollina Why is this |
Notable changes: * buffer: Added `buffer.swap64()` to compliment `swap16()` & `swap32()`. (Zach Bjornson) #7157 * build: New `configure` options have been added for building Node.js as a shared library. (Stefan Budeanu) #6994 - The options are: `--shared`, `--without-v8-platform` & `--without-bundled-v8`. * crypto: Root certificates have been updated. (Ben Noordhuis) #7363 * debugger: The server address is now configurable via `--debug=<address>:<port>`. (Ben Noordhuis) #3316 * npm: Upgraded npm to v3.10.3 (Kat Marchán) #7515 & (Rebecca Turner) #7410 * readline: Added the `prompt` option to the readline constructor. (Evan Lucas) #7125 * repl / vm: `sigint`/`ctrl+c` will now break out of infinite loops without stopping the Node.js instance. (Anna Henningsen) #6635 * src: - Added a `node::FreeEnvironment` public C++ API. (Cheng Zhao) #3098 - Refactored `require('constants')`, constants are now available directly from their respective modules. (James M Snell) #6534 * stream: Improved `readable.read()` performance by up to 70%. (Brian White) #7077 * timers: `setImmediate()` is now up to 150% faster in some situations. (Andras) #6436 * util: Added a `breakLength` option to `util.inspect()` to control how objects are formatted across lines. (cjihrig) #7499 * v8-inspector: Experimental support has been added for debugging Node.js over the inspector protocol. (Ali Ijaz Sheikh) #6792 - *Note: This feature is experimental, and it could be altered or removed.* - You can try this feature by running Node.js with the `--inspect` flag. Refs: #7441 PR-URL: #7550
|
@Fishrock123 avoiding possible breakages in a patch release. IMHO performance optimizations are semver-minor, as performance is a backward-compatible feature. |
|
@mcollina So you are saying this is How this works is, in this order:
|
Notable changes: * buffer: Added `buffer.swap64()` to compliment `swap16()` & `swap32()`. (Zach Bjornson) #7157 * build: New `configure` options have been added for building Node.js as a shared library. (Stefan Budeanu) #6994 - The options are: `--shared`, `--without-v8-platform` & `--without-bundled-v8`. * crypto: Root certificates have been updated. (Ben Noordhuis) #7363 * debugger: The server address is now configurable via `--debug=<address>:<port>`. (Ben Noordhuis) #3316 * npm: Upgraded npm to v3.10.3 (Kat Marchán) #7515 & (Rebecca Turner) #7410 * readline: Added the `prompt` option to the readline constructor. (Evan Lucas) #7125 * repl / vm: `sigint`/`ctrl+c` will now break out of infinite loops without stopping the Node.js instance. (Anna Henningsen) #6635 * src: - Added a `node::FreeEnvironment` public C++ API. (Cheng Zhao) #3098 - Refactored `require('constants')`, constants are now available directly from their respective modules. (James M Snell) #6534 * stream: Improved `readable.read()` performance by up to 70%. (Brian White) #7077 * timers: `setImmediate()` is now up to 150% faster in some situations. (Andras) #6436 * util: Added a `breakLength` option to `util.inspect()` to control how objects are formatted across lines. (cjihrig) #7499 * v8-inspector: Experimental support has been added for debugging Node.js over the inspector protocol. (Ali Ijaz Sheikh) #6792 - *Note: This feature is experimental, and it could be altered or removed.* - You can try this feature by running Node.js with the `--inspect` flag. Refs: #7441 PR-URL: #7550
no and no. This is a performance optimization, e.g. a new feature for me. |
|
So... don't land on LTS is what I'm getting out of this. :) |
|
@Fishrock123 I think this one will be fine on LTS, but I would recommend porting it after some months, not weeks. Something like "land when the new LTS is out". |
Notable changes: * buffer: Added `buffer.swap64()` to compliment `swap16()` & `swap32()`. (Zach Bjornson) #7157 * build: New `configure` options have been added for building Node.js as a shared library. (Stefan Budeanu) #6994 - The options are: `--shared`, `--without-v8-platform` & `--without-bundled-v8`. * crypto: Root certificates have been updated. (Ben Noordhuis) #7363 * debugger: The server address is now configurable via `--debug=<address>:<port>`. (Ben Noordhuis) #3316 * npm: Upgraded npm to v3.10.3 (Kat Marchán) #7515 & (Rebecca Turner) #7410 * readline: Added the `prompt` option to the readline constructor. (Evan Lucas) #7125 * repl / vm: `sigint`/`ctrl+c` will now break out of infinite loops without stopping the Node.js instance. (Anna Henningsen) #6635 * src: - Added a `node::FreeEnvironment` public C++ API. (Cheng Zhao) #3098 - Refactored `require('constants')`, constants are now available directly from their respective modules. (James M Snell) #6534 * stream: Improved `readable.read()` performance by up to 70%. (Brian White) #7077 * timers: `setImmediate()` is now up to 150% faster in some situations. (Andras) #6436 * util: Added a `breakLength` option to `util.inspect()` to control how objects are formatted across lines. (cjihrig) #7499 * v8-inspector: Experimental support has been added for debugging Node.js over the inspector protocol. (Ali Ijaz Sheikh) #6792 - *Note: This feature is experimental, and it could be altered or removed.* - You can try this feature by running Node.js with the `--inspect` flag. Refs: #7441 PR-URL: #7550
### Notable changes * **buffer**: Added `buffer.swap64()` to compliment `swap16()` & `swap32()`. (Zach Bjornson) [#7157](nodejs/node#7157) * **build**: New `configure` options have been added for building Node.js as a shared library. (Stefan Budeanu) [#6994](nodejs/node#6994) - The options are: `--shared`, `--without-v8-platform` & `--without-bundled-v8`. * **crypto**: Root certificates have been updated. (Ben Noordhuis) [#7363](nodejs/node#7363) * **debugger**: The server address is now configurable via `--debug=<address>:<port>`. (Ben Noordhuis) [#3316](nodejs/node#3316) * **npm**: Upgraded npm to v3.10.3 (Kat Marchán) [#7515](nodejs/node#7515) & (Rebecca Turner) [#7410](nodejs/node#7410) * **readline**: Added the `prompt` option to the readline constructor. (Evan Lucas) [#7125](nodejs/node#7125) * **repl / vm**: `sigint`/`ctrl+c` will now break out of infinite loops without stopping the Node.js instance. (Anna Henningsen) [#6635](nodejs/node#6635) * **src**: - Added a `node::FreeEnvironment` public C++ API. (Cheng Zhao) [#3098](nodejs/node#3098) - Refactored `require('constants')`, constants are now available directly from their respective modules. (James M Snell) [#6534](nodejs/node#6534) * **stream**: Improved `readable.read()` performance by up to 70%. (Brian White) [#7077](nodejs/node#7077) * **timers**: `setImmediate()` is now up to 150% faster in some situations. (Andras) [#6436](nodejs/node#6436) * **util**: Added a `breakLength` option to `util.inspect()` to control how objects are formatted across lines. (cjihrig) [#7499](nodejs/node#7499) * **v8-inspector**: Experimental support has been added for debugging Node.js over the inspector protocol. (Ali Ijaz Sheikh) [#6792](nodejs/node#6792) - **Note: This feature is _experimental_, and it could be altered or removed.** - You can try this feature by running Node.js with the `--inspect` flag.
|
@Fishrock123 @mcollina just re your above conversation, this ended up breaking duplexify (https://www.npmjs.com/package/duplexify) because it expected the _buffer to be an array |
|
I feared something like that would have happened. I think we should make a final decision either to semver I'm happy we got this early (before a backport to readable-stream). |
|
They're clearly private. If people want to manipulate them, we can expose public API for that. The duplexify package authors could've pushed/asked for that, and still can imho. |
|
@mcollina could you open a separate issue for the semver discussion so we don't take over this one? for the record i think reading some of the properties in _readableState is essential for a bunch of use-cases. like figuring out if a stream is in objectMode, figuring out if it ended but still has data in its read buffer etc. |
|
@mafintosh done ^ |
Checklist
Affected core subsystem(s)
Description of change
read()performance is improved most by switching from an array to a linked list for storing buffered data. However, other changes that also contribute include: making some hot functions inlinable, fasterread()argument checking, and misc code rearrangement to avoid unnecessary code execution.These improvements only exist for when
nis supplied toread(), otherwise performance is the same.Note: I did change how negative
nvalues are interpreted when in object mode. Before this PR, negativenvalues were interpreted as 1 inhowMuchToRead(). I changed this to instead return 0 to match how negativenvalues are interpreted for non-object mode streams.Results from the included benchmarks: