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: various performance improvements #12361

Closed
wants to merge 3 commits into from

Conversation

mscdex
Copy link
Contributor

@mscdex mscdex commented Apr 12, 2017

Various performance improvements for a few different buffer methods. Here are some results:

                                                                                           improvement confidence      p.value
 buffers/buffer-bytelength.js n=50000000 len=1 encoding="base64"                              51.44 %        *** 1.050242e-53
 buffers/buffer-bytelength.js n=50000000 len=1 encoding="buffer"                               1.42 %         ** 6.738195e-03
 buffers/buffer-bytelength.js n=50000000 len=1 encoding="utf8"                                 7.56 %        *** 5.018577e-22
 buffers/buffer-from.js n=8192 len=10 source="array"                                           6.60 %        *** 1.457931e-18
 buffers/buffer-from.js n=8192 len=10 source="arraybuffer-middle"                              1.07 %            2.401741e-01
 buffers/buffer-from.js n=8192 len=10 source="arraybuffer"                                     1.89 %         ** 7.543607e-03
 buffers/buffer-from.js n=8192 len=10 source="buffer"                                          3.30 %            7.008235e-02
 buffers/buffer-from.js n=8192 len=10 source="object"                                          6.92 %        *** 1.504947e-09
 buffers/buffer-from.js n=8192 len=10 source="string-base64"                                  12.71 %        *** 6.389098e-06
 buffers/buffer-from.js n=8192 len=10 source="string-utf8"                                     4.45 %          * 4.777047e-02
 buffers/buffer-from.js n=8192 len=10 source="string"                                         11.63 %        *** 1.350708e-09
 buffers/buffer-from.js n=8192 len=10 source="uint8array"                                      0.86 %            6.221473e-01
 buffers/buffer-from.js n=2048 len=2048 source="array"                                         0.61 %        *** 8.664083e-05
 buffers/buffer-from.js n=2048 len=2048 source="arraybuffer-middle"                            0.33 %            7.338223e-01
 buffers/buffer-from.js n=2048 len=2048 source="arraybuffer"                                   3.30 %          * 1.755731e-02
 buffers/buffer-from.js n=2048 len=2048 source="buffer"                                        3.02 %        *** 6.629900e-04
 buffers/buffer-from.js n=2048 len=2048 source="object"                                        5.65 %        *** 1.659545e-12
 buffers/buffer-from.js n=2048 len=2048 source="string-base64"                                 2.93 %        *** 1.243836e-06
 buffers/buffer-from.js n=2048 len=2048 source="string-utf8"                                   2.60 %        *** 3.548890e-04
 buffers/buffer-from.js n=2048 len=2048 source="string"                                        5.24 %        *** 7.227091e-11
 buffers/buffer-from.js n=2048 len=2048 source="uint8array"                                   -0.27 %            7.524947e-01
 buffers/buffer-tostring.js n=90000000 len=0 args=1 encoding=""                              260.76 %        *** 3.130638e-38
 buffers/buffer-tostring.js n=90000000 len=0 args=1 encoding="ascii"                         268.52 %        *** 3.255707e-31
 buffers/buffer-tostring.js n=90000000 len=0 args=1 encoding="binary"                        269.05 %        *** 3.730882e-30
 buffers/buffer-tostring.js n=90000000 len=0 args=1 encoding="hex"                           266.61 %        *** 1.917714e-25
 buffers/buffer-tostring.js n=90000000 len=0 args=1 encoding="latin1"                        264.17 %        *** 9.225369e-32
 buffers/buffer-tostring.js n=90000000 len=0 args=1 encoding="UCS-2"                         267.50 %        *** 1.460693e-30
 buffers/buffer-tostring.js n=90000000 len=0 args=1 encoding="utf8"                          263.34 %        *** 4.274071e-31
 buffers/buffer-tostring.js n=40000000 len=64 args=0 encoding=""                               0.87 %            3.249672e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=0 encoding="ascii"                          0.02 %            9.922721e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=0 encoding="binary"                        -2.22 %            3.026759e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=0 encoding="hex"                           -0.19 %            9.182579e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=0 encoding="latin1"                        -0.52 %            7.138981e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=0 encoding="UCS-2"                         -1.10 %            5.829493e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=0 encoding="utf8"                          -1.14 %            3.478206e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=1 encoding=""                               2.81 %        *** 2.749400e-04
 buffers/buffer-tostring.js n=40000000 len=64 args=1 encoding="ascii"                          7.05 %        *** 2.932016e-09
 buffers/buffer-tostring.js n=40000000 len=64 args=1 encoding="binary"                        10.10 %        *** 5.688044e-18
 buffers/buffer-tostring.js n=40000000 len=64 args=1 encoding="hex"                           -0.28 %            8.461152e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=1 encoding="latin1"                         7.96 %        *** 6.284652e-06
 buffers/buffer-tostring.js n=40000000 len=64 args=1 encoding="UCS-2"                         19.49 %        *** 5.979844e-33
 buffers/buffer-tostring.js n=40000000 len=64 args=1 encoding="utf8"                           2.95 %         ** 4.455376e-03
 buffers/buffer-tostring.js n=40000000 len=64 args=2 encoding=""                               3.08 %          * 3.739954e-02
 buffers/buffer-tostring.js n=40000000 len=64 args=2 encoding="ascii"                          6.73 %        *** 2.516403e-07
 buffers/buffer-tostring.js n=40000000 len=64 args=2 encoding="binary"                         9.05 %        *** 1.497619e-13
 buffers/buffer-tostring.js n=40000000 len=64 args=2 encoding="hex"                            0.12 %            9.239700e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=2 encoding="latin1"                        11.31 %        *** 8.922726e-22
 buffers/buffer-tostring.js n=40000000 len=64 args=2 encoding="UCS-2"                         20.40 %        *** 1.096930e-27
 buffers/buffer-tostring.js n=40000000 len=64 args=2 encoding="utf8"                           0.90 %            6.442258e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=3 encoding=""                               2.98 %        *** 3.235235e-05
 buffers/buffer-tostring.js n=40000000 len=64 args=3 encoding="ascii"                          4.20 %          * 1.458188e-02
 buffers/buffer-tostring.js n=40000000 len=64 args=3 encoding="binary"                         6.50 %        *** 7.378602e-05
 buffers/buffer-tostring.js n=40000000 len=64 args=3 encoding="hex"                            0.71 %            5.972208e-01
 buffers/buffer-tostring.js n=40000000 len=64 args=3 encoding="latin1"                         7.37 %        *** 7.379083e-09
 buffers/buffer-tostring.js n=40000000 len=64 args=3 encoding="UCS-2"                         19.33 %        *** 9.793473e-20
 buffers/buffer-tostring.js n=40000000 len=64 args=3 encoding="utf8"                           2.71 %         ** 1.348332e-03
 buffers/buffer-write-string.js n=10000000 len=10 args="" encoding=""                          7.34 %        *** 3.834387e-14
 buffers/buffer-write-string.js n=10000000 len=10 args="" encoding="ascii"                     4.91 %        *** 2.537762e-06
 buffers/buffer-write-string.js n=10000000 len=10 args="" encoding="binary"                    8.11 %        *** 2.907588e-06
 buffers/buffer-write-string.js n=10000000 len=10 args="" encoding="hex"                      -0.77 %            5.734921e-01
 buffers/buffer-write-string.js n=10000000 len=10 args="" encoding="latin1"                    9.29 %        *** 8.819301e-06
 buffers/buffer-write-string.js n=10000000 len=10 args="" encoding="UCS-2"                    18.52 %        *** 1.116642e-33
 buffers/buffer-write-string.js n=10000000 len=10 args="" encoding="utf16le"                  22.72 %        *** 8.339782e-16
 buffers/buffer-write-string.js n=10000000 len=10 args="" encoding="utf8"                      3.93 %         ** 3.174114e-03
 buffers/buffer-write-string.js n=10000000 len=10 args="offset" encoding=""                    4.34 %        *** 1.837325e-05
 buffers/buffer-write-string.js n=10000000 len=10 args="offset" encoding="ascii"               3.82 %         ** 4.578509e-03
 buffers/buffer-write-string.js n=10000000 len=10 args="offset" encoding="binary"              3.02 %            6.567071e-02
 buffers/buffer-write-string.js n=10000000 len=10 args="offset" encoding="hex"                -1.59 %            3.640330e-01
 buffers/buffer-write-string.js n=10000000 len=10 args="offset" encoding="latin1"              4.95 %        *** 4.968388e-06
 buffers/buffer-write-string.js n=10000000 len=10 args="offset" encoding="UCS-2"              13.52 %        *** 4.838675e-15
 buffers/buffer-write-string.js n=10000000 len=10 args="offset" encoding="utf16le"            14.72 %        *** 1.318866e-14
 buffers/buffer-write-string.js n=10000000 len=10 args="offset" encoding="utf8"                1.99 %            1.325214e-01
 buffers/buffer-write-string.js n=10000000 len=10 args="offset+length" encoding=""             4.62 %         ** 7.720895e-03
 buffers/buffer-write-string.js n=10000000 len=10 args="offset+length" encoding="ascii"        5.90 %        *** 5.690321e-06
 buffers/buffer-write-string.js n=10000000 len=10 args="offset+length" encoding="binary"       4.24 %        *** 1.967408e-05
 buffers/buffer-write-string.js n=10000000 len=10 args="offset+length" encoding="hex"          1.22 %            1.347244e-01
 buffers/buffer-write-string.js n=10000000 len=10 args="offset+length" encoding="latin1"       5.61 %        *** 4.559969e-04
 buffers/buffer-write-string.js n=10000000 len=10 args="offset+length" encoding="UCS-2"       14.97 %        *** 1.388892e-15
 buffers/buffer-write-string.js n=10000000 len=10 args="offset+length" encoding="utf16le"     13.35 %        *** 1.915156e-10
 buffers/buffer-write-string.js n=10000000 len=10 args="offset+length" encoding="utf8"         1.63 %            1.468564e-01

I've decided not to mark this as semver-major despite changes such as .toString() now returning early when buf.length === 0, in which case it won't validate the encoding name. The reason being there are already similar short-circuits being done in that method depending on the values of start and end.

As far as I know there shouldn't be any other semver-major-like changes.

CI: https://ci.nodejs.org/job/node-test-pull-request/7352/

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)
  • buffer

@mscdex mscdex added buffer Issues and PRs related to the buffer subsystem. performance Issues and PRs related to the performance of Node.js. labels Apr 12, 2017
@nodejs-github-bot nodejs-github-bot added buffer Issues and PRs related to the buffer subsystem. c++ Issues and PRs that require attention from people who are familiar with C++. util Issues and PRs related to the built-in util module. labels Apr 12, 2017
addaleax pushed a commit to addaleax/node that referenced this pull request Apr 14, 2017
PR-URL: nodejs#12361
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
addaleax pushed a commit to addaleax/node that referenced this pull request Apr 14, 2017
PR-URL: nodejs#12361
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
addaleax pushed a commit to addaleax/node that referenced this pull request Apr 14, 2017
PR-URL: nodejs#12361
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
@addaleax
Copy link
Member

Landed in 46f2026...4749ec2

@addaleax addaleax closed this Apr 14, 2017
@mscdex mscdex deleted the buffer-perf branch April 14, 2017 21:13
@Trott
Copy link
Member

Trott commented Apr 16, 2017

Not sure if it's too late to do anything, but I think this should have technically been semver-major because it changes an error message.

Before:

> Buffer.from('foo','ajdkl')
TypeError: "encoding" must be a valid string encoding
...

After:

> Buffer.from('foo','ajdkl')
TypeError: Unknown encoding: ajdkl
...

The code that produces the first error message above is preserved, but it is moved to a location where it will never execute.

Unfortunately, this wasn't caught by tests because the only test case we have for that error (in test-buffer-alloc.js) only checks that it's a TypeError but does not check the value of the message:

assert.throws(() => Buffer.from('', 'buffer'), TypeError);

@Trott Trott added the semver-major PRs that contain breaking changes and should be released in the next major version. label Apr 16, 2017
@mscdex
Copy link
Contributor Author

mscdex commented Apr 16, 2017

@Trott I think that can be easily fixed without affecting anything performance-wise.

@mscdex
Copy link
Contributor Author

mscdex commented Apr 16, 2017

This should no longer be semver-major when landed with #12439.

@mscdex mscdex mentioned this pull request Apr 16, 2017
2 tasks
@mscdex mscdex removed the semver-major PRs that contain breaking changes and should be released in the next major version. label Apr 18, 2017
@mscdex
Copy link
Contributor Author

mscdex commented Apr 18, 2017

I'm dropping semver-major now that the regression fix has landed, in case we should want to land/backport these two PRs in other branches in the future ...

evanlucas pushed a commit that referenced this pull request Apr 25, 2017
PR-URL: #12361
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
@evanlucas evanlucas mentioned this pull request May 1, 2017
evanlucas pushed a commit that referenced this pull request May 1, 2017
PR-URL: #12361
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
evanlucas pushed a commit that referenced this pull request May 2, 2017
PR-URL: #12361
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
@MylesBorins MylesBorins added the baking-for-lts PRs that need to wait before landing in a LTS release. label May 15, 2017
@MylesBorins
Copy link
Contributor

@mscdex should this be backported? If not please add the do-not-land label

@mscdex
Copy link
Contributor Author

mscdex commented May 15, 2017

@MylesBorins It would probably need some benchmarking first to be sure it's still faster in previous V8 versions.

@gibfahn
Copy link
Member

gibfahn commented Jun 18, 2017

Should land with #12439.

@MylesBorins MylesBorins added dont-land-on-v6.x and removed baking-for-lts PRs that need to wait before landing in a LTS release. lts-watch-v6.x labels Dec 19, 2017
@MylesBorins
Copy link
Contributor

MylesBorins commented Dec 19, 2017

I'm opting to not land this as we are getting close to maintenance

if we change our mind we need to also include #14131

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. c++ Issues and PRs that require attention from people who are familiar with C++. performance Issues and PRs related to the performance of Node.js. util Issues and PRs related to the built-in util module.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants