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

buffer: Preallocate array with buffer length in Buffer#toJSON #11733

Closed
wants to merge 1 commit into from
Closed

buffer: Preallocate array with buffer length in Buffer#toJSON #11733

wants to merge 1 commit into from

Conversation

alemures
Copy link
Contributor

@alemures alemures commented Mar 7, 2017

Because the final array length is known, it's better to allocate its
final length at initialization time to avoid future reallocations.

It also adds an explicit buffer length greater than 0 comparison so
it's more readable, avoids the internal ToBoolean call and follows the
standard Node.js API format (as it can be checked in other similar
structures where 'length > 0' is preferred over 'length')

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines
Affected core subsystem(s)

buffer

@nodejs-github-bot nodejs-github-bot added the buffer Issues and PRs related to the buffer subsystem. label Mar 7, 2017
@mscdex
Copy link
Contributor

mscdex commented Mar 7, 2017

I think I'm -1 on this. See this relevant comment. It's not immediately clear what branches this change affects (negatively) performance-wise, as I'm not sure which (if any) have had the appropriate patches backported from upstream V8.

@alemures
Copy link
Contributor Author

alemures commented Mar 7, 2017

There is actually a benchmark created in the last update of this function "benchmark/buffers/buffer-tojson.js". It could be useful to know if this change have had some performance improvement, I'll be able to get some results in a while.

@ChALkeR
Copy link
Member

ChALkeR commented Mar 7, 2017

Note that the commit message does not follow commit guidelines atm — the subsystem is not present.

@alemures
Copy link
Contributor Author

alemures commented Mar 8, 2017

Here I have some interesting results from the benchmark mentioned before showing up to 3 times more operations for the bigger buffer:

master

buffers/buffer-tojson.js len=0 n=10000: 5,084,450.175184731
buffers/buffer-tojson.js len=10 n=10000: 3,875,130.882545558
buffers/buffer-tojson.js len=256 n=10000: 593,240.6046854025
buffers/buffer-tojson.js len=4096 n=10000: 42,223.39550717062

Actual PR

buffers/buffer-tojson.js len=0 n=10000: 5,515,017.115855619
buffers/buffer-tojson.js len=10 n=10000: 4,850,801.473673488
buffers/buffer-tojson.js len=256 n=10000: 1,448,223.8258887387
buffers/buffer-tojson.js len=4096 n=10000: 149,254.77835441532

@mscdex
Copy link
Contributor

mscdex commented Mar 11, 2017

I just checked the results on each versioned branch and master, and it does provide about the same performance or faster in each case, so LGTM.

@ChALkeR
Copy link
Member

ChALkeR commented Mar 11, 2017

The commit message still needs to be fixed =).

@alemures
Copy link
Contributor Author

I'll get the commit message fixed shortly, I suppose it can be done for already pushed commits.

subsystem: buffer

Because the final array length is known, it's better to allocate its
final length at initialization time to avoid future reallocations.

It also adds an explicit buffer length greater than 0 comparison so
it's more readable, avoids the internal ToBoolean call and follows the
standard Node.js API format (as it can be checked in other similar
structures where 'length > 0' is preferred over 'length')
@alemures
Copy link
Contributor Author

I just fixed the commit message adding the subsystem and fixing a couple of spelling mistakes.

Apart from that, I have been doing tests removing the "if(this.length > 0)... else" and i am getting exactly the same results when the buffer's length is 0. If there is no other reason why we are using this if statement other than performance, I will suggest to remove it so the code will look more polished and simple.

@TimothyGu
Copy link
Member

I will suggest to remove it so the code will look more polished and simple.

Can you do that while at it?

@alemures
Copy link
Contributor Author

I just ran the benchmark without the if...else statement and the results are exactly the same so, I suppose that it doesn't affect performance.

buffers/buffer-tojson.js len=0 n=10000: 5,342,776.512727028
buffers/buffer-tojson.js len=10 n=10000: 5,032,158.005735653
buffers/buffer-tojson.js len=256 n=10000: 1,420,578.24069056
buffers/buffer-tojson.js len=4096 n=10000: 144,037.6943189128

@jasnell
Copy link
Member

jasnell commented Apr 4, 2017

@jasnell
Copy link
Member

jasnell commented Apr 4, 2017

@alemures ... can you look at #11733 (comment), thank you!

@alemures
Copy link
Contributor Author

alemures commented Apr 5, 2017

@jasnell I proposed a small style change to this PR but I'm not sure if you guys agree or not. I suppose that it's better to leave as it is now that CI reported no errors with the actual code. Do you think it is still worth it the change?

@jasnell
Copy link
Member

jasnell commented Apr 6, 2017

I'm good with this as is. Will get it landed.

jasnell pushed a commit that referenced this pull request Apr 6, 2017
Because the final array length is known, it's better to allocate its
final length at initialization time to avoid future reallocations.

Also add an explicit buffer length greater than 0 comparison so
it's more readable, avoids the internal ToBoolean call and follows the
standard Node.js API format (as it can be checked in other similar
structures where 'length > 0' is preferred over 'length')

PR-URL: #11733
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
@jasnell
Copy link
Member

jasnell commented Apr 6, 2017

landed in 51587b2

@jasnell jasnell closed this Apr 6, 2017
italoacasas pushed a commit to italoacasas/node that referenced this pull request Apr 10, 2017
Because the final array length is known, it's better to allocate its
final length at initialization time to avoid future reallocations.

Also add an explicit buffer length greater than 0 comparison so
it's more readable, avoids the internal ToBoolean call and follows the
standard Node.js API format (as it can be checked in other similar
structures where 'length > 0' is preferred over 'length')

PR-URL: nodejs#11733
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
@italoacasas italoacasas mentioned this pull request Apr 10, 2017
2 tasks
@MylesBorins
Copy link
Contributor

@mscdex are you ok with the way this change landed? I'm seeing the original -1 but no sign off

Also curious if this should be backported

@mscdex
Copy link
Contributor

mscdex commented Apr 19, 2017

@MylesBorins It would need to be benchmarked first, I'm not sure the performance fix for new Array(len) was ever backported to older branches. Without that, these changes will make it slower (compared to initializing with []).

@MylesBorins MylesBorins added the baking-for-lts PRs that need to wait before landing in a LTS release. label May 15, 2017
@MylesBorins MylesBorins removed the baking-for-lts PRs that need to wait before landing in a LTS release. label Aug 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
buffer Issues and PRs related to the buffer subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants