Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

streams: performance improvements for clearBuffer in Writable #3751

Closed
wants to merge 2 commits into from

Conversation

mcollina
Copy link
Member

This commits removes a function allocation inside the clearBuffer function. Moreover, it adds counting of buffered chunks to instantiate a fixed-sized Array. The performance improvements are in the range
5-50%, depending on the usecase.

Here is gist of the results of the http benchmarks in node on my MacBook Pro Late 2014 (i7, 16GB of RAM): https://gist.github.com/mcollina/5c59c057cb5b138fcd70.

cc @trevnorris @lucamaraschi @nodejs/benchmarking

@Fishrock123 Fishrock123 added the stream Issues and PRs related to the stream subsystem. label Nov 10, 2015
@geek
Copy link
Member

geek commented Nov 10, 2015

LGTM

@Fishrock123
Copy link
Contributor

cc @nodejs/streams

var entry = state.corkedCbs;
var cbs = entry.cbs;

state.corkedCbs = entry.next;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this property already been set on the object? If not I would suggest placing it, even just this.corkedCbs = null; in the constructor. This will help prevent the object map from changing, and aide the optimizing compiler.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mafintosh
Copy link
Member

👍 from me

@lucamaraschi
Copy link
Contributor

👍 LGTM

});

if (state.corkedCbs) {
state.corkedCbs.next = new CorkCbs(cbs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this only ever be two corkedCbs long? If we already have corkedCbs, and it has .next assigned, will we replace it with a new set of callbacks?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semi colon

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chrisdickinson good spot! I planned to write more about this! My understanding is that it is only 2 corkedCbs long. Maybe I am wrong, see these lines, the callback can be deferred on the nextTick: https://github.com/mcollina/node/blob/perf-clearBuffer/lib/_stream_writable.js#L360-L364.

There might also be a different way to implement that, maybe having an array with two objects, and a even/odd counter.

@chrisdickinson
Copy link
Contributor

I like the direction this is going! I might be misunderstanding this bit though — is this behavior intended?

if (state.corkedCbs) {
state.corkedCbs.next = new CorkCbs(cbs)
} else {
state.corkedCbs = new CorkCbs(cbs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semi colon

@mcollina
Copy link
Member Author

I've renamed the field, changed the little class into CorkedCbs, and added the missing semicolons.

@chrisdickinson are you happy with my explanation on the double element? Do you see another (possibly faster) way to implement this?

@jasnell
Copy link
Member

jasnell commented Nov 12, 2015

LGTM

@chrisdickinson
Copy link
Contributor

@chrisdickinson are you happy with my explanation on the double element? Do you see another (possibly faster) way to implement this?

I think so, though I might suggest adding a comment (or an assert) stating that we only ever expect two of these per stream. Thanks for bearing with me!

@mcollina
Copy link
Member Author

@chrisdickinson I have added an assert and a comment. It should be ok now.

Let me know if it is ok and I'll squash my commits.

@jasnell
Copy link
Member

jasnell commented Nov 15, 2015

@jasnell
Copy link
Member

jasnell commented Nov 15, 2015

CI Looks good. Couple of related failures.

@mcollina
Copy link
Member Author

@jasnell anything I should look into/fix? It seems there are windows-specific and arm-specific failures.

On a window configuration, test-child-process-fork-regr-gh-2847.js is failing.

On ARM, I can't access https://ci.nodejs.org/job/node-test-commit-arm/1188/nodes=armv7-wheezy/tapTestReport/ (I get a Gateway Timeout) - so I can't really know.

On ARM fanned (what does that mean?), I'm getting a timeout/failure on test-crypto-dh.js.

@jasnell
Copy link
Member

jasnell commented Nov 15, 2015

There's nothing you need to do. The issues are with the CI environment
itself unfortunately
On Nov 15, 2015 2:22 AM, "Matteo Collina" [email protected] wrote:

@jasnell https://github.com/jasnell anything I should look into/fix? It
seems there are windows-specific and arm-specific failures.

On a window configuration, test-child-process-fork-regr-gh-2847
https://github.com/nodejs/node/issues/2847.js is failing.

On ARM, I can't access
https://ci.nodejs.org/job/node-test-commit-arm/1188/nodes=armv7-wheezy/tapTestReport/
(I get a Gateway Timeout) - so I can't really know.

On ARM fanned (what does that mean?), I'm getting a timeout/failure on
test-crypto-dh.js.


Reply to this email directly or view it on GitHub
#3751 (comment).

@chrisdickinson
Copy link
Contributor

LGTM — I don't have access to the CI server at the moment, perhaps @jasnell can restart CI?

@MylesBorins
Copy link
Contributor

@rvagg
Copy link
Member

rvagg commented Dec 2, 2015

@chrisdickinson:

I don't have access to the CI server at the moment

Do you mean technically or you're on your phone or something that makes it impractical? If you technically can't access it then we should sort that out!

@chrisdickinson
Copy link
Contributor

@rvagg: ah! I take it back. Last I checked I was in a weird state where I could kind of log in using the old pw auth, but it seems to have resolved. False alarm!

This commits removes a function allocation inside the clearBuffer
function. Moreover, it adds counting of buffered chunks to instantiate
a fixed-sized Array. The performance improvements are in the range
5-50%, depending on the usecase.
@mcollina
Copy link
Member Author

I've run this on the CI, and I'm getting a possibly unrelated failure on node-test-binary-windows: https://ci.nodejs.org/job/node-test-binary-windows/301/.

(I've rebased this to master, and squashed the commits)

@chrisdickinson @jasnell if you folks are good with this, I would like to get this merged at some point this week.

@cjihrig
Copy link
Contributor

cjihrig commented Dec 14, 2015

Those are known flakey tests, so LGTM.

@chrisdickinson
Copy link
Contributor

Yep, LGTM — Feel free to merge at will!

@mcollina
Copy link
Member Author

I've been working on this for the last two days :D.

Turn out V8 is improved in the latest update, and this is not needed anymore in this current form. I am so happy to be proven wrong, because it means all the node apps will be really faster soon, for free.

However there is still the original use case I discovered this for (100+ chunks for a single _writev) that is not covered, plus a general cleanup of that area.

I will submit a separate PR for that, referencing this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.