Skip to content

buffer: various performance improvements - #12361

Closed
mscdex wants to merge 3 commits into
nodejs:masterfrom
mscdex:buffer-perf
Closed

mscdex wants to merge 3 commits into
nodejs:masterfrom
mscdex:buffer-perf

Conversation

@mscdex

@mscdex mscdex commented Apr 12, 2017 •

Copy link
Copy Markdown
Contributor

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

Details
                                                                                           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 <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
addaleax pushed a commit to addaleax/node that referenced this pull request Apr 14, 2017
PR-URL: nodejs#12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
addaleax pushed a commit to addaleax/node that referenced this pull request Apr 14, 2017
PR-URL: nodejs#12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@addaleax

Copy link
Copy Markdown
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

Trott commented Apr 16, 2017

Copy link
Copy Markdown
Member

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

mscdex commented Apr 16, 2017

Copy link
Copy Markdown
Contributor Author

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

@mscdex

mscdex commented Apr 16, 2017

Copy link
Copy Markdown
Contributor Author

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

@mscdex mscdex mentioned this pull request Apr 16, 2017
2 tasks done
@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

mscdex commented Apr 18, 2017 •

Copy link
Copy Markdown
Contributor Author

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 <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@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 <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
evanlucas pushed a commit that referenced this pull request May 2, 2017
PR-URL: #12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@MylesBorins MylesBorins added the baking-for-lts PRs whose changes need more time before an LTS backport. label May 15, 2017
@MylesBorins

Copy link
Copy Markdown
Contributor

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

@mscdex

mscdex commented May 15, 2017

Copy link
Copy Markdown
Contributor Author

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

@jasnell jasnell mentioned this pull request May 11, 2017
@gibfahn gibfahn mentioned this pull request Jun 18, 2017
3 tasks done
@gibfahn

gibfahn commented Jun 18, 2017

Copy link
Copy Markdown
Member

Should land with #12439.

@MylesBorins MylesBorins added dont-land-on-v6.x and removed baking-for-lts PRs whose changes need more time before an LTS backport. lts-watch-v6.x labels Dec 19, 2017
@MylesBorins

MylesBorins commented Dec 19, 2017 •

Copy link
Copy Markdown
Contributor

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

@ChALkeR ChALkeR mentioned this pull request May 30, 2019
4 tasks
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