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
base: master
from

Conversation

Projects
None yet
7 participants
@mscdex
Contributor

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 added some commits Apr 10, 2017

addaleax added a commit to addaleax/node that referenced this pull request Apr 14, 2017

buffer: optimize from() and byteLength()
PR-URL: nodejs#12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>

addaleax added a commit to addaleax/node that referenced this pull request Apr 14, 2017

buffer: optimize toString()
PR-URL: nodejs#12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>

addaleax added a commit to addaleax/node that referenced this pull request Apr 14, 2017

buffer: optimize write()
PR-URL: nodejs#12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax
Member

addaleax commented Apr 14, 2017

Landed in 46f2026...4749ec2

@addaleax addaleax closed this Apr 14, 2017

@mscdex mscdex deleted the mscdex:buffer-perf branch Apr 14, 2017

@Trott

This comment has been minimized.

Show comment
Hide comment
@Trott

Trott Apr 16, 2017

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);
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 label Apr 16, 2017

@mscdex

This comment has been minimized.

Show comment
Hide comment
@mscdex

mscdex Apr 16, 2017

Contributor

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

Contributor

mscdex commented Apr 16, 2017

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

@mscdex

This comment has been minimized.

Show comment
Hide comment
@mscdex

mscdex Apr 16, 2017

Contributor

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

Contributor

mscdex commented Apr 16, 2017

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

@mscdex mscdex referenced this pull request Apr 16, 2017

Closed

buffer: remove unreachable code #12438

2 of 2 tasks complete

@mscdex mscdex removed the semver-major label Apr 18, 2017

@mscdex

This comment has been minimized.

Show comment
Hide comment
@mscdex

mscdex Apr 18, 2017

Contributor

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 ...

Contributor

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 added a commit that referenced this pull request Apr 25, 2017

buffer: optimize write()
PR-URL: #12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>

@evanlucas evanlucas referenced this pull request May 1, 2017

Merged

v7.10.0 proposal #12775

evanlucas added a commit that referenced this pull request May 1, 2017

buffer: optimize write()
PR-URL: #12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>

evanlucas added a commit that referenced this pull request May 2, 2017

buffer: optimize write()
PR-URL: #12361
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@MylesBorins

This comment has been minimized.

Show comment
Hide comment
@MylesBorins

MylesBorins May 15, 2017

Member

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

Member

MylesBorins commented May 15, 2017

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

@mscdex

This comment has been minimized.

Show comment
Hide comment
@mscdex

mscdex May 15, 2017

Contributor

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

Contributor

mscdex commented May 15, 2017

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

@jasnell jasnell referenced this pull request May 11, 2017

Closed

8.0.0 Release Proposal #12220

@gibfahn gibfahn referenced this pull request Jun 18, 2017

Closed

buffer: fix backwards incompatibility #12439

3 of 3 tasks complete
@gibfahn

This comment has been minimized.

Show comment
Hide comment
@gibfahn

gibfahn Jun 18, 2017

Member

Should land with #12439.

Member

gibfahn commented Jun 18, 2017

Should land with #12439.

@MylesBorins

This comment has been minimized.

Show comment
Hide comment
@MylesBorins

MylesBorins Dec 19, 2017

Member

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

Member

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