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: directly use ArrayBuffer as the pool #8302

Closed
wants to merge 1 commit into from

Conversation

addaleax
Copy link
Member

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

buffer

Description of change

Make the buffer pool an ArrayBuffer which is used directly, speeding up allocation noticeably in some cases.
The only drawback happens when creating pool-based Buffer instances from strings whose byte lengths got overestimated by Buffer.byteLength, e.g. for base64-encoded strings containing whitespace, where two Buffer instances are being created.

This may also be useful when providing Buffer classes in the future.

Benchmark results for benchmark/buffers/buffer-creation.js:

                                 improvement significant      p.value
len=1024 type="buffer()"             47.11 %         *** 5.202555e-12
len=1024 type="fast-alloc"           -3.41 %             3.823226e-01
len=1024 type="fast-alloc-fill"       1.11 %             7.985624e-01
len=1024 type="fast-allocUnsafe"     24.37 %         *** 4.264084e-05
len=1024 type="slow"                  4.81 %             2.634609e-01
len=1024 type="slow-allocUnsafe"      1.28 %             7.864850e-01
len=10 type="buffer()"               59.42 %         *** 9.953552e-13
len=10 type="fast-alloc"             -6.43 %             1.450524e-01
len=10 type="fast-alloc-fill"        -2.96 %             4.873766e-01
len=10 type="fast-allocUnsafe"       33.89 %         *** 6.517268e-07
len=10 type="slow"                   -1.48 %             7.357711e-01
len=10 type="slow-allocUnsafe"        0.04 %             9.939576e-01
len=2048 type="buffer()"             36.34 %         *** 3.201045e-10
len=2048 type="fast-alloc"           -4.67 %             2.172900e-01
len=2048 type="fast-alloc-fill"      -0.15 %             9.732945e-01
len=2048 type="fast-allocUnsafe"     20.13 %         *** 2.372115e-04
len=2048 type="slow"                  4.35 %             2.831340e-01
len=2048 type="slow-allocUnsafe"      1.13 %             8.055388e-01
len=4096 type="buffer()"              4.90 %             2.495340e-01
len=4096 type="fast-alloc"           -2.11 %             5.417520e-01
len=4096 type="fast-alloc-fill"      -0.29 %             9.460378e-01
len=4096 type="fast-allocUnsafe"      3.11 %             5.001959e-01
len=4096 type="slow"                  0.95 %             8.145888e-01
len=4096 type="slow-allocUnsafe"      3.74 %             4.227627e-01
len=8192 type="buffer()"              5.08 %             2.263029e-01
len=8192 type="fast-alloc"           -1.16 %             7.300235e-01
len=8192 type="fast-alloc-fill"       0.40 %             9.179919e-01
len=8192 type="fast-allocUnsafe"      5.16 %             2.591544e-01
len=8192 type="slow"                  2.57 %             5.212449e-01
len=8192 type="slow-allocUnsafe"     -3.19 %             4.699138e-01

(raw data)

/cc @nodejs/buffer

Make the buffer pool an `ArrayBuffer` which is used directly,
speeding up allocation noticeably in some cases.
The only drawback happens when creating pool-based `Buffer`
instances from strings whose byte lengths got overestimated
by `Buffer.byteLength`, e.g. for base64-encoded strings
containing whitespace, where two `Buffer` instances are
being created.

This may also be useful when providing Buffer classes in
the future.

Benchmark results for `benchmark/buffers/buffer-creation.js`:

```
                                 improvement significant      p.value
len=1024 type="buffer()"             47.11 %         *** 5.202555e-12
len=1024 type="fast-alloc"           -3.41 %             3.823226e-01
len=1024 type="fast-alloc-fill"       1.11 %             7.985624e-01
len=1024 type="fast-allocUnsafe"     24.37 %         *** 4.264084e-05
len=1024 type="slow"                  4.81 %             2.634609e-01
len=1024 type="slow-allocUnsafe"      1.28 %             7.864850e-01
len=10 type="buffer()"               59.42 %         *** 9.953552e-13
len=10 type="fast-alloc"             -6.43 %             1.450524e-01
len=10 type="fast-alloc-fill"        -2.96 %             4.873766e-01
len=10 type="fast-allocUnsafe"       33.89 %         *** 6.517268e-07
len=10 type="slow"                   -1.48 %             7.357711e-01
len=10 type="slow-allocUnsafe"        0.04 %             9.939576e-01
len=2048 type="buffer()"             36.34 %         *** 3.201045e-10
len=2048 type="fast-alloc"           -4.67 %             2.172900e-01
len=2048 type="fast-alloc-fill"      -0.15 %             9.732945e-01
len=2048 type="fast-allocUnsafe"     20.13 %         *** 2.372115e-04
len=2048 type="slow"                  4.35 %             2.831340e-01
len=2048 type="slow-allocUnsafe"      1.13 %             8.055388e-01
len=4096 type="buffer()"              4.90 %             2.495340e-01
len=4096 type="fast-alloc"           -2.11 %             5.417520e-01
len=4096 type="fast-alloc-fill"      -0.29 %             9.460378e-01
len=4096 type="fast-allocUnsafe"      3.11 %             5.001959e-01
len=4096 type="slow"                  0.95 %             8.145888e-01
len=4096 type="slow-allocUnsafe"      3.74 %             4.227627e-01
len=8192 type="buffer()"              5.08 %             2.263029e-01
len=8192 type="fast-alloc"           -1.16 %             7.300235e-01
len=8192 type="fast-alloc-fill"       0.40 %             9.179919e-01
len=8192 type="fast-allocUnsafe"      5.16 %             2.591544e-01
len=8192 type="slow"                  2.57 %             5.212449e-01
len=8192 type="slow-allocUnsafe"     -3.19 %             4.699138e-01
```
@addaleax addaleax added buffer Issues and PRs related to the buffer subsystem. dont-land-on-v4.x performance Issues and PRs related to the performance of Node.js. labels Aug 27, 2016
@addaleax
Copy link
Member Author

@trevnorris
Copy link
Contributor

LGTM. There's no change to user API since .buffer returns the ArrayBuffer and .parent returns .buffer. So at most this is a semver-minor.

@jasnell
Copy link
Member

jasnell commented Aug 29, 2016

LGTM

@addaleax
Copy link
Member Author

addaleax commented Sep 2, 2016

Landed in 2c9a86f

@addaleax addaleax closed this Sep 2, 2016
@addaleax addaleax deleted the buffer-arraybuffer-pool branch September 2, 2016 10:47
addaleax added a commit that referenced this pull request Sep 2, 2016
Make the buffer pool an `ArrayBuffer` which is used directly,
speeding up allocation noticeably in some cases.
The only drawback happens when creating pool-based `Buffer`
instances from strings whose byte lengths got overestimated
by `Buffer.byteLength`, e.g. for base64-encoded strings
containing whitespace, where two `Buffer` instances are
being created.

This may also be useful when providing Buffer classes in
the future.

Benchmark results for `benchmark/buffers/buffer-creation.js`:

```
                                 improvement significant      p.value
len=1024 type="buffer()"             47.11 %         *** 5.202555e-12
len=1024 type="fast-alloc"           -3.41 %             3.823226e-01
len=1024 type="fast-alloc-fill"       1.11 %             7.985624e-01
len=1024 type="fast-allocUnsafe"     24.37 %         *** 4.264084e-05
len=1024 type="slow"                  4.81 %             2.634609e-01
len=1024 type="slow-allocUnsafe"      1.28 %             7.864850e-01
len=10 type="buffer()"               59.42 %         *** 9.953552e-13
len=10 type="fast-alloc"             -6.43 %             1.450524e-01
len=10 type="fast-alloc-fill"        -2.96 %             4.873766e-01
len=10 type="fast-allocUnsafe"       33.89 %         *** 6.517268e-07
len=10 type="slow"                   -1.48 %             7.357711e-01
len=10 type="slow-allocUnsafe"        0.04 %             9.939576e-01
len=2048 type="buffer()"             36.34 %         *** 3.201045e-10
len=2048 type="fast-alloc"           -4.67 %             2.172900e-01
len=2048 type="fast-alloc-fill"      -0.15 %             9.732945e-01
len=2048 type="fast-allocUnsafe"     20.13 %         *** 2.372115e-04
len=2048 type="slow"                  4.35 %             2.831340e-01
len=2048 type="slow-allocUnsafe"      1.13 %             8.055388e-01
len=4096 type="buffer()"              4.90 %             2.495340e-01
len=4096 type="fast-alloc"           -2.11 %             5.417520e-01
len=4096 type="fast-alloc-fill"      -0.29 %             9.460378e-01
len=4096 type="fast-allocUnsafe"      3.11 %             5.001959e-01
len=4096 type="slow"                  0.95 %             8.145888e-01
len=4096 type="slow-allocUnsafe"      3.74 %             4.227627e-01
len=8192 type="buffer()"              5.08 %             2.263029e-01
len=8192 type="fast-alloc"           -1.16 %             7.300235e-01
len=8192 type="fast-alloc-fill"       0.40 %             9.179919e-01
len=8192 type="fast-allocUnsafe"      5.16 %             2.591544e-01
len=8192 type="slow"                  2.57 %             5.212449e-01
len=8192 type="slow-allocUnsafe"     -3.19 %             4.699138e-01
```

PR-URL: #8302
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@Fishrock123 Fishrock123 mentioned this pull request Sep 6, 2016
@Fishrock123
Copy link
Contributor

Depends on #7082, can't land on v6.

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. performance Issues and PRs related to the performance of Node.js.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants