Skip to content

buffer: always use _copy for copy#62032

Closed
ronag wants to merge 1 commit intonodejs:mainfrom
ronag:copyActual
Closed

buffer: always use _copy for copy#62032
ronag wants to merge 1 commit intonodejs:mainfrom
ronag:copyActual

Conversation

@ronag
Copy link
Member

@ronag ronag commented Feb 27, 2026

This fixes a performance regression for Buffer.copy(target, 0) and brings it back inline with Buffer.write.

V8 has a massive TypedArray.prototype.set penalty on SharedArrayBuffer

Buffer.set and Buffer.copy are up to 8.4x slower when writing to a SharedArrayBuffer vs a regular ArrayBuffer, while Buffer.write (string encoding) is completely unaffected.

256 bytes, varying offset (Apple M3 Pro, Node 25.6.1):
                  ArrayBuffer    SharedArrayBuffer    Slowdown
Buffer.set           13.6 ns             56.1 ns       4.1x
Buffer.copy          17.0 ns             65.1 ns       3.8x
Buffer.write         75.8 ns             74.1 ns       1.0x (unaffected)

4096 bytes, varying offset:
                  ArrayBuffer    SharedArrayBuffer    Slowdown
Buffer.set           80.3 ns            674.2 ns       8.4x
Buffer.copy          78.4 ns            677.7 ns       8.6x
Buffer.write        190.6 ns            186.1 ns       1.0x (unaffected)

@nodejs-github-bot nodejs-github-bot added buffer Issues and PRs related to the buffer subsystem. needs-ci PRs that need a full CI run. labels Feb 27, 2026
@ronag ronag changed the title buffer: always us _copy for copy buffer: always use _copy for copy Feb 27, 2026
@Renegade334
Copy link
Member

If the figures from #60399 still apply for ArrayBuffer-backed buffers, is there scope to add isArrayBuffer(TypedArrayPrototypeGetBuffer(target)) to the previous conditions, and get the best of both worlds?

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@ronag
Copy link
Member Author

ronag commented Feb 27, 2026

If the figures from #60399 still apply for ArrayBuffer-backed buffers, is there scope to add isArrayBuffer(TypedArrayPrototypeGetBuffer(target)) to the previous conditions, and get the best of both worlds?

doing all of these type checks also adds overhead. Furthermore the benchmark from that PR apply to concat so it's unclear what it's actual effect on Buffer.copy is...

@ronag ronag added the request-ci Add this label to start a Jenkins CI on a PR. label Feb 27, 2026
@RafaelGSS RafaelGSS added the performance Issues and PRs related to the performance of Node.js. label Feb 27, 2026
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Feb 27, 2026
@nodejs-github-bot
Copy link
Collaborator

@codecov
Copy link

codecov bot commented Feb 27, 2026

Codecov Report

βœ… All modified and coverable lines are covered by tests.
βœ… Project coverage is 89.69%. Comparing base (35d3bc8) to head (e88373d).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62032      +/-   ##
==========================================
+ Coverage   89.65%   89.69%   +0.03%     
==========================================
  Files         676      676              
  Lines      206231   206236       +5     
  Branches    39505    39759     +254     
==========================================
+ Hits       184898   184981      +83     
+ Misses      13463    13404      -59     
+ Partials     7870     7851      -19     
Files with missing lines Coverage Ξ”
lib/buffer.js 99.15% <100.00%> (-0.01%) ⬇️

... and 28 files with indirect coverage changes

πŸš€ New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • πŸ“¦ JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@Renegade334 Renegade334 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think it's worth mentioning in the commit message that this is essentially a reversion of 24bebd0, sans tests.

This fixes a performance regression for Buffer.copy(target, 0) and brings it back inline with Buffer.write.

V8 has a massive TypedArray.prototype.set penalty on SharedArrayBuffer

Buffer.set and Buffer.copy are up to 8.4x slower when writing to a SharedArrayBuffer vs a regular ArrayBuffer, while Buffer.write (string encoding) is completely unaffected.

256 bytes, varying offset (Apple M3 Pro, Node 25.6.1):

                  ArrayBuffer    SharedArrayBuffer    Slowdown
Buffer.set           13.6 ns             56.1 ns       4.1x
Buffer.copy          17.0 ns             65.1 ns       3.8x
Buffer.write         75.8 ns             74.1 ns       1.0x (unaffected)
4096 bytes, varying offset:

                  ArrayBuffer    SharedArrayBuffer    Slowdown
Buffer.set           80.3 ns            674.2 ns       8.4x
Buffer.copy          78.4 ns            677.7 ns       8.6x
Buffer.write        190.6 ns            186.1 ns       1.0x (unaffected)
@ronag ronag requested a review from RafaelGSS February 28, 2026 08:11
@ronag ronag added the request-ci Add this label to start a Jenkins CI on a PR. label Feb 28, 2026
@github-actions github-actions bot added request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Feb 28, 2026
@github-actions
Copy link
Contributor

Failed to start CI
   ⚠  Commits were pushed since the last approving review:
   ⚠  - buffer: always use _copy for copy
   ✘  Refusing to run CI on potentially unsafe PR
https://github.com/nodejs/node/actions/runs/22516891493

@ronag ronag added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Feb 28, 2026
@richardlau richardlau removed the request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. label Feb 28, 2026
@gurgunday gurgunday added the needs-benchmark-ci PR that need a benchmark CI run. label Feb 28, 2026
Copy link
Member

@gurgunday gurgunday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am seeing a significant regression in non-partial copy performance:

node % ./node benchmark/buffers/buffer-copy.js
buffers/buffer-copy.js n=6000000 partial="true" bytes=8: 37,745,651.53108819
buffers/buffer-copy.js n=6000000 partial="false" bytes=8: 72,230,886.31703596
buffers/buffer-copy.js n=6000000 partial="true" bytes=128: 37,269,250.926878504
buffers/buffer-copy.js n=6000000 partial="false" bytes=128: 70,233,110.24800341
buffers/buffer-copy.js n=6000000 partial="true" bytes=1024: 26,739,253.757964805
buffers/buffer-copy.js n=6000000 partial="false" bytes=1024: 37,699,305.6259145

node % ./node-ronag benchmark/buffers/buffer-copy.js
buffers/buffer-copy.js n=6000000 partial="true" bytes=8: 36,820,630.5993248
buffers/buffer-copy.js n=6000000 partial="false" bytes=8: 37,401,995.084754474
buffers/buffer-copy.js n=6000000 partial="true" bytes=128: 37,360,956.762793645
buffers/buffer-copy.js n=6000000 partial="false" bytes=128: 35,075,651.428067446
buffers/buffer-copy.js n=6000000 partial="true" bytes=1024: 26,155,344.217952482
buffers/buffer-copy.js n=6000000 partial="false" bytes=1024: 22,480,048.984626204

Those checks are necessary to hit the V8 .set optimization, it is faster than our native copy, I think we should instead make those checks more strict if you found a case that's slower, as @Renegade334 suggested

You are right that .concat no longer hits that path, but copy still does

Cc @ChALkeR

@aduh95
Copy link
Contributor

aduh95 commented Feb 28, 2026

Benchmark CI: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/1805/

Results
confidence improvement accuracy (*)    (**)   (***)
buffers/buffer-atob.js n=1000000 size=128                                                                                                                      -0.49 %       Β±1.61%  Β±2.15%  Β±2.80%
buffers/buffer-atob.js n=1000000 size=16                                                                                                                       -0.75 %       Β±1.78%  Β±2.37%  Β±3.10%
buffers/buffer-atob.js n=1000000 size=32                                                                                                                       -0.49 %       Β±1.52%  Β±2.03%  Β±2.64%
buffers/buffer-atob.js n=1000000 size=64                                                                                                                       -0.83 %       Β±1.81%  Β±2.41%  Β±3.14%
buffers/buffer-base64-decode-wrapped.js n=32 linesCount=524288 charsPerLine=76                                                                                 -0.27 %       Β±0.89%  Β±1.18%  Β±1.54%
buffers/buffer-base64-decode.js size=8388608 n=32                                                                                                              -0.06 %       Β±0.17%  Β±0.22%  Β±0.29%
buffers/buffer-base64-encode.js n=32 len=67108864                                                                                                              -0.02 %       Β±0.10%  Β±0.13%  Β±0.17%
buffers/buffer-base64url-decode.js size=8388608 n=32                                                                                                            0.05 %       Β±0.17%  Β±0.23%  Β±0.30%
buffers/buffer-base64url-encode.js n=32 len=67108864                                                                                                            0.03 %       Β±0.08%  Β±0.10%  Β±0.13%
buffers/buffer-btoa.js n=1000000 size=1024                                                                                                               *      1.09 %       Β±0.85%  Β±1.13%  Β±1.48%
buffers/buffer-btoa.js n=1000000 size=128                                                                                                                *      1.95 %       Β±1.87%  Β±2.49%  Β±3.24%
buffers/buffer-btoa.js n=1000000 size=16                                                                                                                       -1.04 %       Β±1.85%  Β±2.47%  Β±3.21%
buffers/buffer-btoa.js n=1000000 size=256                                                                                                                      -0.08 %       Β±1.81%  Β±2.42%  Β±3.15%
buffers/buffer-btoa.js n=1000000 size=32                                                                                                                       -0.86 %       Β±2.06%  Β±2.74%  Β±3.57%
buffers/buffer-btoa.js n=1000000 size=64                                                                                                                       -0.63 %       Β±1.65%  Β±2.19%  Β±2.87%
buffers/buffer-bytelength-buffer.js n=4000000 len=16                                                                                                           -1.51 %       Β±3.26%  Β±4.33%  Β±5.64%
buffers/buffer-bytelength-buffer.js n=4000000 len=2                                                                                                             0.40 %       Β±3.28%  Β±4.37%  Β±5.68%
buffers/buffer-bytelength-buffer.js n=4000000 len=256                                                                                                           1.18 %       Β±2.60%  Β±3.46%  Β±4.51%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='base64' type='four_bytes'                                                                      0.44 %       Β±2.84%  Β±3.78%  Β±4.92%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='base64' type='latin1'                                                                   *     -3.34 %       Β±2.61%  Β±3.48%  Β±4.54%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='base64' type='one_byte'                                                                **     -4.10 %       Β±2.65%  Β±3.54%  Β±4.62%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='base64' type='three_bytes'                                                                     1.57 %       Β±1.99%  Β±2.64%  Β±3.45%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='base64' type='two_bytes'                                                                       1.39 %       Β±2.60%  Β±3.46%  Β±4.50%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='utf8' type='four_bytes'                                                                       -0.77 %       Β±1.58%  Β±2.10%  Β±2.74%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='utf8' type='latin1'                                                                            1.47 %       Β±2.33%  Β±3.10%  Β±4.03%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='utf8' type='one_byte'                                                                          2.14 %       Β±2.38%  Β±3.17%  Β±4.12%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='utf8' type='three_bytes'                                                                       1.42 %       Β±1.92%  Β±2.55%  Β±3.32%
buffers/buffer-bytelength-string.js n=4000000 repeat=1 encoding='utf8' type='two_bytes'                                                                        -0.04 %       Β±1.83%  Β±2.44%  Β±3.18%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='base64' type='four_bytes'                                                                     0.44 %       Β±2.50%  Β±3.32%  Β±4.33%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='base64' type='latin1'                                                                         0.46 %       Β±2.48%  Β±3.31%  Β±4.31%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='base64' type='one_byte'                                                                       1.80 %       Β±2.89%  Β±3.85%  Β±5.01%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='base64' type='three_bytes'                                                                   -1.71 %       Β±2.33%  Β±3.10%  Β±4.03%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='base64' type='two_bytes'                                                                     -0.20 %       Β±2.90%  Β±3.85%  Β±5.02%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='utf8' type='four_bytes'                                                                       0.02 %       Β±0.12%  Β±0.16%  Β±0.21%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='utf8' type='latin1'                                                                           0.16 %       Β±0.97%  Β±1.29%  Β±1.68%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='utf8' type='one_byte'                                                                        -0.27 %       Β±3.36%  Β±4.47%  Β±5.81%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='utf8' type='three_bytes'                                                                     -0.01 %       Β±0.44%  Β±0.59%  Β±0.77%
buffers/buffer-bytelength-string.js n=4000000 repeat=16 encoding='utf8' type='two_bytes'                                                                        0.11 %       Β±0.50%  Β±0.66%  Β±0.86%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='base64' type='four_bytes'                                                                      0.71 %       Β±2.57%  Β±3.41%  Β±4.44%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='base64' type='latin1'                                                                         -0.27 %       Β±2.58%  Β±3.43%  Β±4.47%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='base64' type='one_byte'                                                                        2.22 %       Β±3.02%  Β±4.02%  Β±5.23%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='base64' type='three_bytes'                                                                     1.53 %       Β±2.43%  Β±3.24%  Β±4.22%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='base64' type='two_bytes'                                                                      -0.08 %       Β±2.79%  Β±3.71%  Β±4.83%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='utf8' type='four_bytes'                                                                        0.33 %       Β±0.71%  Β±0.95%  Β±1.23%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='utf8' type='latin1'                                                                            0.63 %       Β±3.06%  Β±4.08%  Β±5.31%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='utf8' type='one_byte'                                                                          0.43 %       Β±3.83%  Β±5.10%  Β±6.63%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='utf8' type='three_bytes'                                                                      -0.05 %       Β±1.25%  Β±1.67%  Β±2.17%
buffers/buffer-bytelength-string.js n=4000000 repeat=2 encoding='utf8' type='two_bytes'                                                                        -0.40 %       Β±1.33%  Β±1.76%  Β±2.30%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='base64' type='four_bytes'                                                                    1.46 %       Β±2.65%  Β±3.53%  Β±4.59%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='base64' type='latin1'                                                                       -1.15 %       Β±2.40%  Β±3.20%  Β±4.16%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='base64' type='one_byte'                                                                     -2.75 %       Β±2.89%  Β±3.85%  Β±5.01%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='base64' type='three_bytes'                                                                  -0.47 %       Β±2.85%  Β±3.79%  Β±4.94%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='base64' type='two_bytes'                                                                    -1.25 %       Β±2.26%  Β±3.00%  Β±3.91%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='utf8' type='four_bytes'                                                                     -0.00 %       Β±0.00%  Β±0.01%  Β±0.01%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='utf8' type='latin1'                                                                          0.10 %       Β±0.14%  Β±0.19%  Β±0.25%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='utf8' type='one_byte'                                                                       -0.55 %       Β±1.37%  Β±1.82%  Β±2.38%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='utf8' type='three_bytes'                                                                     0.13 %       Β±0.19%  Β±0.25%  Β±0.33%
buffers/buffer-bytelength-string.js n=4000000 repeat=256 encoding='utf8' type='two_bytes'                                                                      -0.00 %       Β±0.02%  Β±0.03%  Β±0.04%
buffers/buffer-compare-instance-method.js n=1000000 args=1 size=16                                                                                              1.89 %       Β±2.48%  Β±3.30%  Β±4.30%
buffers/buffer-compare-instance-method.js n=1000000 args=1 size=16386                                                                                          -2.22 %       Β±2.80%  Β±3.77%  Β±4.99%
buffers/buffer-compare-instance-method.js n=1000000 args=1 size=4096                                                                                           -1.83 %       Β±2.55%  Β±3.41%  Β±4.46%
buffers/buffer-compare-instance-method.js n=1000000 args=1 size=512                                                                                            -3.33 %       Β±3.87%  Β±5.16%  Β±6.72%
buffers/buffer-compare-instance-method.js n=1000000 args=2 size=16                                                                                             -0.66 %       Β±2.37%  Β±3.15%  Β±4.11%
buffers/buffer-compare-instance-method.js n=1000000 args=2 size=16386                                                                                           3.34 %       Β±3.68%  Β±4.90%  Β±6.38%
buffers/buffer-compare-instance-method.js n=1000000 args=2 size=4096                                                                                           -0.91 %       Β±3.02%  Β±4.02%  Β±5.23%
buffers/buffer-compare-instance-method.js n=1000000 args=2 size=512                                                                                             1.86 %       Β±2.46%  Β±3.27%  Β±4.25%
buffers/buffer-compare-instance-method.js n=1000000 args=5 size=16                                                                                             -0.18 %       Β±3.71%  Β±4.93%  Β±6.42%
buffers/buffer-compare-instance-method.js n=1000000 args=5 size=16386                                                                                           1.37 %       Β±4.11%  Β±5.47%  Β±7.12%
buffers/buffer-compare-instance-method.js n=1000000 args=5 size=4096                                                                                            1.26 %       Β±2.95%  Β±3.92%  Β±5.11%
buffers/buffer-compare-instance-method.js n=1000000 args=5 size=512                                                                                             0.58 %       Β±3.25%  Β±4.32%  Β±5.62%
buffers/buffer-compare-offset.js n=1000000 size=16 method='offset'                                                                                             -0.21 %       Β±1.76%  Β±2.34%  Β±3.05%
buffers/buffer-compare-offset.js n=1000000 size=16 method='slice'                                                                                      ***     -2.59 %       Β±1.44%  Β±1.92%  Β±2.52%
buffers/buffer-compare-offset.js n=1000000 size=16386 method='offset'                                                                                           0.20 %       Β±2.09%  Β±2.79%  Β±3.63%
buffers/buffer-compare-offset.js n=1000000 size=16386 method='slice'                                                                                     *      1.73 %       Β±1.50%  Β±2.01%  Β±2.62%
buffers/buffer-compare-offset.js n=1000000 size=4096 method='offset'                                                                                           -0.54 %       Β±2.03%  Β±2.70%  Β±3.52%
buffers/buffer-compare-offset.js n=1000000 size=4096 method='slice'                                                                                            -0.98 %       Β±1.48%  Β±1.97%  Β±2.56%
buffers/buffer-compare-offset.js n=1000000 size=512 method='offset'                                                                                            -0.32 %       Β±1.97%  Β±2.63%  Β±3.43%
buffers/buffer-compare-offset.js n=1000000 size=512 method='slice'                                                                                              0.58 %       Β±1.84%  Β±2.45%  Β±3.19%
buffers/buffer-compare.js n=1000000 size=16                                                                                                                    -0.76 %       Β±1.78%  Β±2.37%  Β±3.09%
buffers/buffer-compare.js n=1000000 size=16386                                                                                                         ***    -13.81 %       Β±2.56%  Β±3.42%  Β±4.49%
buffers/buffer-compare.js n=1000000 size=4096                                                                                                                  -0.92 %       Β±3.38%  Β±4.50%  Β±5.86%
buffers/buffer-compare.js n=1000000 size=512                                                                                                                    0.36 %       Β±1.27%  Β±1.70%  Β±2.21%
buffers/buffer-concat-fill.js n=800000 extraSize=1                                                                                                              0.00 %       Β±0.88%  Β±1.17%  Β±1.52%
buffers/buffer-concat-fill.js n=800000 extraSize=1024                                                                                                           0.08 %       Β±0.93%  Β±1.24%  Β±1.62%
buffers/buffer-concat-fill.js n=800000 extraSize=256                                                                                                            0.25 %       Β±0.98%  Β±1.31%  Β±1.70%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=16                                                                                      -0.26 %       Β±0.95%  Β±1.27%  Β±1.65%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=4                                                                                       -0.54 %       Β±1.53%  Β±2.03%  Β±2.65%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=16                                                                                     -0.31 %       Β±1.44%  Β±1.92%  Β±2.50%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=4                                                                                      -1.55 %       Β±1.69%  Β±2.26%  Β±2.95%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=16                                                                                     0.45 %       Β±0.59%  Β±0.79%  Β±1.02%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=4                                                                                      0.78 %       Β±1.04%  Β±1.38%  Β±1.80%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=16                                                                                *     -2.35 %       Β±1.90%  Β±2.54%  Β±3.33%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=4                                                                                       -0.02 %       Β±1.98%  Β±2.63%  Β±3.42%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=16                                                                                      0.69 %       Β±1.50%  Β±2.00%  Β±2.60%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=4                                                                                      -0.40 %       Β±1.89%  Β±2.52%  Β±3.28%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=16                                                                                     0.32 %       Β±0.66%  Β±0.88%  Β±1.14%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=4                                                                                     -0.04 %       Β±0.95%  Β±1.26%  Β±1.64%
buffers/buffer-copy.js n=6000000 partial='false' bytes=1024                                                                                            ***    -41.41 %       Β±1.43%  Β±1.92%  Β±2.54%
buffers/buffer-copy.js n=6000000 partial='false' bytes=128                                                                                             ***    -46.13 %       Β±2.10%  Β±2.82%  Β±3.73%
buffers/buffer-copy.js n=6000000 partial='false' bytes=8                                                                                               ***    -48.07 %       Β±2.43%  Β±3.27%  Β±4.32%
buffers/buffer-copy.js n=6000000 partial='true' bytes=1024                                                                                                      0.31 %       Β±1.01%  Β±1.34%  Β±1.74%
buffers/buffer-copy.js n=6000000 partial='true' bytes=128                                                                                               **      1.71 %       Β±0.99%  Β±1.32%  Β±1.72%
buffers/buffer-copy.js n=6000000 partial='true' bytes=8                                                                                                         0.33 %       Β±1.12%  Β±1.49%  Β±1.94%
buffers/buffer-creation.js n=600000 len=10 type='fast-alloc-fill'                                                                                               0.99 %       Β±4.90%  Β±6.52%  Β±8.49%
buffers/buffer-creation.js n=600000 len=10 type='fast-alloc'                                                                                                    1.46 %       Β±5.32%  Β±7.08%  Β±9.21%
buffers/buffer-creation.js n=600000 len=10 type='fast-allocUnsafe'                                                                                       *      4.83 %       Β±4.70%  Β±6.26%  Β±8.14%
buffers/buffer-creation.js n=600000 len=10 type='slow-allocUnsafe'                                                                                              1.39 %       Β±5.64%  Β±7.50%  Β±9.77%
buffers/buffer-creation.js n=600000 len=1024 type='fast-alloc-fill'                                                                                            -0.63 %       Β±0.86%  Β±1.15%  Β±1.49%
buffers/buffer-creation.js n=600000 len=1024 type='fast-alloc'                                                                                                  0.06 %       Β±0.80%  Β±1.06%  Β±1.38%
buffers/buffer-creation.js n=600000 len=1024 type='fast-allocUnsafe'                                                                                           -0.51 %       Β±1.52%  Β±2.03%  Β±2.64%
buffers/buffer-creation.js n=600000 len=1024 type='slow-allocUnsafe'                                                                                           -0.01 %       Β±0.88%  Β±1.17%  Β±1.53%
buffers/buffer-creation.js n=600000 len=4096 type='fast-alloc-fill'                                                                                             0.37 %       Β±0.94%  Β±1.26%  Β±1.66%
buffers/buffer-creation.js n=600000 len=4096 type='fast-alloc'                                                                                                  0.20 %       Β±0.91%  Β±1.21%  Β±1.58%
buffers/buffer-creation.js n=600000 len=4096 type='fast-allocUnsafe'                                                                                           -0.21 %       Β±0.86%  Β±1.14%  Β±1.48%
buffers/buffer-creation.js n=600000 len=4096 type='slow-allocUnsafe'                                                                                            0.19 %       Β±0.68%  Β±0.90%  Β±1.17%
buffers/buffer-creation.js n=600000 len=8192 type='fast-alloc-fill'                                                                                            -0.70 %       Β±0.81%  Β±1.08%  Β±1.40%
buffers/buffer-creation.js n=600000 len=8192 type='fast-alloc'                                                                                                  0.01 %       Β±0.74%  Β±0.98%  Β±1.28%
buffers/buffer-creation.js n=600000 len=8192 type='fast-allocUnsafe'                                                                                            0.28 %       Β±0.80%  Β±1.06%  Β±1.39%
buffers/buffer-creation.js n=600000 len=8192 type='slow-allocUnsafe'                                                                                            0.56 %       Β±0.92%  Β±1.23%  Β±1.60%
buffers/buffer-equals.js n=1000000 difflen='false' size=0                                                                                                      -0.03 %       Β±3.76%  Β±5.01%  Β±6.55%
buffers/buffer-equals.js n=1000000 difflen='false' size=16386                                                                                          ***     19.68 %       Β±1.99%  Β±2.68%  Β±3.55%
buffers/buffer-equals.js n=1000000 difflen='false' size=512                                                                                                    -0.80 %       Β±2.29%  Β±3.05%  Β±3.98%
buffers/buffer-equals.js n=1000000 difflen='true' size=0                                                                                                        1.95 %       Β±3.03%  Β±4.06%  Β±5.35%
buffers/buffer-equals.js n=1000000 difflen='true' size=16386                                                                                                    2.61 %       Β±2.86%  Β±3.83%  Β±5.03%
buffers/buffer-equals.js n=1000000 difflen='true' size=512                                                                                                      0.20 %       Β±1.23%  Β±1.64%  Β±2.15%
buffers/buffer-fill.js n=20000 size=65536 type='fill("")'                                                                                                      -3.26 %       Β±3.26%  Β±4.35%  Β±5.68%
buffers/buffer-fill.js n=20000 size=65536 type='fill("t", "utf8")'                                                                                              0.69 %       Β±3.45%  Β±4.60%  Β±6.01%
buffers/buffer-fill.js n=20000 size=65536 type='fill("t", 0, "utf8")'                                                                                           0.23 %       Β±3.44%  Β±4.59%  Β±5.98%
buffers/buffer-fill.js n=20000 size=65536 type='fill("t", 0)'                                                                                                   0.02 %       Β±1.64%  Β±2.18%  Β±2.84%
buffers/buffer-fill.js n=20000 size=65536 type='fill("t")'                                                                                                     -0.32 %       Β±3.78%  Β±5.03%  Β±6.55%
buffers/buffer-fill.js n=20000 size=65536 type='fill("test")'                                                                                                  -2.57 %       Β±3.66%  Β±4.88%  Β±6.38%
buffers/buffer-fill.js n=20000 size=65536 type='fill(0)'                                                                                                       -0.66 %       Β±1.98%  Β±2.64%  Β±3.43%
buffers/buffer-fill.js n=20000 size=65536 type='fill(100)'                                                                                                      0.12 %       Β±2.23%  Β±2.97%  Β±3.87%
buffers/buffer-fill.js n=20000 size=65536 type='fill(400)'                                                                                                     -1.11 %       Β±2.21%  Β±2.94%  Β±3.82%
buffers/buffer-fill.js n=20000 size=65536 type='fill(Buffer.alloc(1), 0)'                                                                                *     -4.15 %       Β±3.29%  Β±4.39%  Β±5.72%
buffers/buffer-fill.js n=20000 size=8192 type='fill("")'                                                                                                       -0.92 %       Β±7.59% Β±10.10% Β±13.15%
buffers/buffer-fill.js n=20000 size=8192 type='fill("t", "utf8")'                                                                                              -1.26 %      Β±11.97% Β±15.93% Β±20.74%
buffers/buffer-fill.js n=20000 size=8192 type='fill("t", 0, "utf8")'                                                                                           -0.27 %       Β±8.22% Β±10.94% Β±14.24%
buffers/buffer-fill.js n=20000 size=8192 type='fill("t", 0)'                                                                                                   -5.22 %       Β±8.66% Β±11.53% Β±15.03%
buffers/buffer-fill.js n=20000 size=8192 type='fill("t")'                                                                                                       1.07 %      Β±11.75% Β±15.64% Β±20.36%
buffers/buffer-fill.js n=20000 size=8192 type='fill("test")'                                                                                                   -4.68 %       Β±9.07% Β±12.08% Β±15.74%
buffers/buffer-fill.js n=20000 size=8192 type='fill(0)'                                                                                                         0.37 %       Β±1.37%  Β±1.83%  Β±2.39%
buffers/buffer-fill.js n=20000 size=8192 type='fill(100)'                                                                                                *      2.13 %       Β±1.82%  Β±2.42%  Β±3.15%
buffers/buffer-fill.js n=20000 size=8192 type='fill(400)'                                                                                                       0.76 %       Β±1.63%  Β±2.17%  Β±2.82%
buffers/buffer-fill.js n=20000 size=8192 type='fill(Buffer.alloc(1), 0)'                                                                                       -2.87 %      Β±10.03% Β±13.34% Β±17.37%
buffers/buffer-from.js n=800000 len=100 source='array'                                                                                                         -0.36 %       Β±1.48%  Β±1.97%  Β±2.57%
buffers/buffer-from.js n=800000 len=100 source='arraybuffer-middle'                                                                                            -3.78 %       Β±3.91%  Β±5.21%  Β±6.80%
buffers/buffer-from.js n=800000 len=100 source='arraybuffer'                                                                                                    1.91 %       Β±3.80%  Β±5.06%  Β±6.59%
buffers/buffer-from.js n=800000 len=100 source='buffer'                                                                                                        -0.38 %       Β±2.60%  Β±3.46%  Β±4.51%
buffers/buffer-from.js n=800000 len=100 source='object'                                                                                                         1.92 %       Β±3.57%  Β±4.75%  Β±6.18%
buffers/buffer-from.js n=800000 len=100 source='string-base64'                                                                                                 -0.54 %       Β±1.33%  Β±1.77%  Β±2.30%
buffers/buffer-from.js n=800000 len=100 source='string-utf8'                                                                                                   -0.28 %       Β±2.15%  Β±2.86%  Β±3.72%
buffers/buffer-from.js n=800000 len=100 source='string'                                                                                                         0.93 %       Β±1.83%  Β±2.44%  Β±3.17%
buffers/buffer-from.js n=800000 len=100 source='uint16array'                                                                                                   -0.25 %       Β±2.20%  Β±2.93%  Β±3.81%
buffers/buffer-from.js n=800000 len=100 source='uint8array'                                                                                             **     -4.77 %       Β±3.06%  Β±4.08%  Β±5.33%
buffers/buffer-from.js n=800000 len=2048 source='array'                                                                                                 **     -0.38 %       Β±0.28%  Β±0.38%  Β±0.49%
buffers/buffer-from.js n=800000 len=2048 source='arraybuffer-middle'                                                                                     *     -3.39 %       Β±2.69%  Β±3.58%  Β±4.67%
buffers/buffer-from.js n=800000 len=2048 source='arraybuffer'                                                                                                  -1.50 %       Β±3.30%  Β±4.39%  Β±5.73%
buffers/buffer-from.js n=800000 len=2048 source='buffer'                                                                                                        0.40 %       Β±1.23%  Β±1.64%  Β±2.14%
buffers/buffer-from.js n=800000 len=2048 source='object'                                                                                                       -0.90 %       Β±4.87%  Β±6.48%  Β±8.44%
buffers/buffer-from.js n=800000 len=2048 source='string-base64'                                                                                                 0.64 %       Β±0.81%  Β±1.08%  Β±1.40%
buffers/buffer-from.js n=800000 len=2048 source='string-utf8'                                                                                                   0.86 %       Β±0.89%  Β±1.18%  Β±1.54%
buffers/buffer-from.js n=800000 len=2048 source='string'                                                                                                        0.29 %       Β±1.00%  Β±1.34%  Β±1.74%
buffers/buffer-from.js n=800000 len=2048 source='uint16array'                                                                                                   0.30 %       Β±0.80%  Β±1.06%  Β±1.39%
buffers/buffer-from.js n=800000 len=2048 source='uint8array'                                                                                            **      1.42 %       Β±0.97%  Β±1.29%  Β±1.69%
buffers/buffer-hex-decode.js n=1000000 len=1024                                                                                                                -0.22 %       Β±0.64%  Β±0.85%  Β±1.11%
buffers/buffer-hex-decode.js n=1000000 len=64                                                                                                                   0.15 %       Β±1.93%  Β±2.58%  Β±3.36%
buffers/buffer-hex-encode.js n=1000000 len=1024                                                                                                                -0.15 %       Β±0.23%  Β±0.31%  Β±0.40%
buffers/buffer-hex-encode.js n=1000000 len=64                                                                                                                   0.22 %       Β±0.93%  Β±1.23%  Β±1.61%
buffers/buffer-indexof-number.js n=1000000 value=64                                                                                                            -0.93 %       Β±2.86%  Β±3.80%  Β±4.95%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='--l'                                                                              -0.11 %       Β±0.35%  Β±0.47%  Β±0.61%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='@'                                                                                -7.11 %      Β±10.22% Β±13.61% Β±17.71%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='</i> to the Caterpillar'                                                           0.02 %       Β±0.09%  Β±0.12%  Β±0.16%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='aaaaaaaaaaaaaaaaa'                                                                 0.07 %       Β±0.09%  Β±0.11%  Β±0.15%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='Alice'                                                                            -0.49 %      Β±13.47% Β±17.92% Β±23.33%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='found it very'                                                                     0.00 %       Β±0.03%  Β±0.04%  Β±0.05%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='Gryphon'                                                                          -0.21 %       Β±1.70%  Β±2.26%  Β±2.95%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='neighbouring pool'                                                                 0.06 %       Β±0.08%  Β±0.10%  Β±0.13%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='Ou est ma chatte?'                                                                -0.01 %       Β±0.19%  Β±0.25%  Β±0.33%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='SQ'                                                                                0.26 %       Β±2.40%  Β±3.19%  Β±4.15%
buffers/buffer-indexof.js n=50000 type='buffer' encoding='undefined' search='venture to go near the house till she had brought herself down to'                 1.17 %       Β±1.76%  Β±2.37%  Β±3.14%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='--l'                                                                                   -0.49 %       Β±0.92%  Β±1.24%  Β±1.64%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='@'                                                                              **      8.41 %       Β±5.40%  Β±7.23%  Β±9.50%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='</i> to the Caterpillar'                                                               -1.33 %       Β±2.73%  Β±3.64%  Β±4.74%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='aaaaaaaaaaaaaaaaa'                                                                      1.45 %       Β±3.20%  Β±4.27%  Β±5.59%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='Alice'                                                                                  9.85 %      Β±10.01% Β±13.34% Β±17.40%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='found it very'                                                                          0.07 %       Β±0.47%  Β±0.63%  Β±0.82%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='Gryphon'                                                                                0.49 %       Β±1.06%  Β±1.42%  Β±1.87%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='neighbouring pool'                                                                      0.23 %       Β±2.35%  Β±3.12%  Β±4.06%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='Ou est ma chatte?'                                                                     -0.54 %       Β±2.01%  Β±2.68%  Β±3.49%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='SQ'                                                                                    -0.32 %       Β±1.46%  Β±1.95%  Β±2.53%
buffers/buffer-indexof.js n=50000 type='string' encoding='ucs2' search='venture to go near the house till she had brought herself down to'                     -0.70 %       Β±1.17%  Β±1.57%  Β±2.08%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='--l'                                                                                   -0.01 %       Β±0.40%  Β±0.53%  Β±0.69%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='@'                                                                                     -1.01 %       Β±6.22%  Β±8.28% Β±10.78%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='</i> to the Caterpillar'                                                               -0.20 %       Β±1.45%  Β±1.93%  Β±2.51%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='aaaaaaaaaaaaaaaaa'                                                                      1.09 %       Β±1.50%  Β±2.02%  Β±2.67%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='Alice'                                                                                 -1.49 %       Β±9.52% Β±12.67% Β±16.49%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='found it very'                                                                         -0.23 %       Β±0.82%  Β±1.10%  Β±1.43%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='Gryphon'                                                                               -0.12 %       Β±0.72%  Β±0.96%  Β±1.24%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='neighbouring pool'                                                                     -0.25 %       Β±0.78%  Β±1.04%  Β±1.36%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='Ou est ma chatte?'                                                              **     -0.18 %       Β±0.12%  Β±0.15%  Β±0.20%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='SQ'                                                                                    -0.49 %       Β±2.56%  Β±3.41%  Β±4.44%
buffers/buffer-indexof.js n=50000 type='string' encoding='utf8' search='venture to go near the house till she had brought herself down to'                     -0.03 %       Β±0.19%  Β±0.26%  Β±0.34%
buffers/buffer-isascii.js input='hello world' length='long' n=20000000                                                                                 ***      7.46 %       Β±2.43%  Β±3.24%  Β±4.24%
buffers/buffer-isascii.js input='hello world' length='short' n=20000000                                                                                 **      3.50 %       Β±2.36%  Β±3.15%  Β±4.13%
buffers/buffer-isutf8.js input='βˆ€xβˆˆβ„: ⌈xβŒ‰ = βˆ’βŒŠβˆ’xβŒ‹' length='long' n=20000000                                                                                     0.04 %       Β±0.10%  Β±0.13%  Β±0.17%
buffers/buffer-isutf8.js input='βˆ€xβˆˆβ„: ⌈xβŒ‰ = βˆ’βŒŠβˆ’xβŒ‹' length='short' n=20000000                                                                                    0.52 %       Β±1.19%  Β±1.59%  Β±2.07%
buffers/buffer-isutf8.js input='regular string' length='long' n=20000000                                                                                        1.82 %       Β±4.96%  Β±6.60%  Β±8.59%
buffers/buffer-isutf8.js input='regular string' length='short' n=20000000                                                                                       0.36 %       Β±0.84%  Β±1.12%  Β±1.47%
buffers/buffer-iterate.js n=1000 method='for' type='fast' size=16386                                                                                            1.36 %       Β±4.86%  Β±6.46%  Β±8.41%
buffers/buffer-iterate.js n=1000 method='for' type='fast' size=4096                                                                                            -1.03 %       Β±7.65% Β±10.18% Β±13.27%
buffers/buffer-iterate.js n=1000 method='for' type='fast' size=512                                                                                              2.46 %      Β±17.28% Β±22.99% Β±29.93%
buffers/buffer-iterate.js n=1000 method='forOf' type='fast' size=16386                                                                                         -0.51 %       Β±1.34%  Β±1.78%  Β±2.32%
buffers/buffer-iterate.js n=1000 method='forOf' type='fast' size=4096                                                                                          -4.18 %       Β±5.54%  Β±7.37%  Β±9.60%
buffers/buffer-iterate.js n=1000 method='forOf' type='fast' size=512                                                                                            0.69 %      Β±14.00% Β±18.63% Β±24.24%
buffers/buffer-iterate.js n=1000 method='iterator' type='fast' size=16386                                                                                      -0.39 %       Β±1.38%  Β±1.83%  Β±2.38%
buffers/buffer-iterate.js n=1000 method='iterator' type='fast' size=4096                                                                                        1.00 %       Β±2.69%  Β±3.58%  Β±4.66%
buffers/buffer-iterate.js n=1000 method='iterator' type='fast' size=512                                                                                         3.66 %      Β±12.68% Β±16.87% Β±21.96%
buffers/buffer-normalize-encoding.js n=1000000 encoding='ascii'                                                                                                 2.84 %       Β±3.30%  Β±4.41%  Β±5.78%
buffers/buffer-normalize-encoding.js n=1000000 encoding='base64'                                                                                                0.59 %       Β±1.55%  Β±2.06%  Β±2.68%
buffers/buffer-normalize-encoding.js n=1000000 encoding='BASE64'                                                                                                1.12 %       Β±4.06%  Β±5.42%  Β±7.09%
buffers/buffer-normalize-encoding.js n=1000000 encoding='binary'                                                                                               -0.35 %       Β±4.58%  Β±6.10%  Β±7.94%
buffers/buffer-normalize-encoding.js n=1000000 encoding='hex'                                                                                                   0.00 %       Β±1.17%  Β±1.56%  Β±2.04%
buffers/buffer-normalize-encoding.js n=1000000 encoding='HEX'                                                                                                   1.75 %       Β±5.29%  Β±7.04%  Β±9.17%
buffers/buffer-normalize-encoding.js n=1000000 encoding='latin1'                                                                                               -1.70 %       Β±5.14%  Β±6.84%  Β±8.90%
buffers/buffer-normalize-encoding.js n=1000000 encoding='LATIN1'                                                                                               -2.37 %       Β±3.33%  Β±4.43%  Β±5.78%
buffers/buffer-normalize-encoding.js n=1000000 encoding='UCS-2'                                                                                                -0.47 %       Β±3.59%  Β±4.78%  Β±6.22%
buffers/buffer-normalize-encoding.js n=1000000 encoding='UCS2'                                                                                                 -1.01 %       Β±3.89%  Β±5.18%  Β±6.75%
buffers/buffer-normalize-encoding.js n=1000000 encoding='utf-16le'                                                                                              0.48 %       Β±2.09%  Β±2.79%  Β±3.63%
buffers/buffer-normalize-encoding.js n=1000000 encoding='UTF-16LE'                                                                                             -0.98 %       Β±5.11%  Β±6.81%  Β±8.86%
buffers/buffer-normalize-encoding.js n=1000000 encoding='utf-8'                                                                                                -0.72 %       Β±1.50%  Β±1.99%  Β±2.59%
buffers/buffer-normalize-encoding.js n=1000000 encoding='utf16le'                                                                                              -0.51 %       Β±1.48%  Β±1.97%  Β±2.57%
buffers/buffer-normalize-encoding.js n=1000000 encoding='UTF16LE'                                                                                              -4.09 %       Β±5.13%  Β±6.82%  Β±8.88%
buffers/buffer-normalize-encoding.js n=1000000 encoding='utf8'                                                                                                 -0.84 %       Β±1.22%  Β±1.63%  Β±2.12%
buffers/buffer-normalize-encoding.js n=1000000 encoding='UTF8'                                                                                                 -0.57 %       Β±1.92%  Β±2.55%  Β±3.32%
buffers/buffer-read-float.js n=1000000 value='big' endian='LE' type='Double'                                                                                   12.67 %      Β±17.39% Β±23.14% Β±30.12%
buffers/buffer-read-float.js n=1000000 value='big' endian='LE' type='Float'                                                                                     4.28 %      Β±18.35% Β±24.41% Β±31.78%
buffers/buffer-read-float.js n=1000000 value='inf' endian='LE' type='Double'                                                                                   -0.48 %      Β±16.82% Β±22.38% Β±29.13%
buffers/buffer-read-float.js n=1000000 value='inf' endian='LE' type='Float'                                                                                   -12.07 %      Β±16.67% Β±22.21% Β±28.97%
buffers/buffer-read-float.js n=1000000 value='nan' endian='LE' type='Double'                                                                                   -4.55 %      Β±16.65% Β±22.15% Β±28.83%
buffers/buffer-read-float.js n=1000000 value='nan' endian='LE' type='Float'                                                                                    -8.69 %      Β±16.20% Β±21.57% Β±28.10%
buffers/buffer-read-float.js n=1000000 value='small' endian='LE' type='Double'                                                                                  4.88 %      Β±16.50% Β±21.95% Β±28.57%
buffers/buffer-read-float.js n=1000000 value='small' endian='LE' type='Float'                                                                                  -3.27 %      Β±15.74% Β±20.95% Β±27.27%
buffers/buffer-read-float.js n=1000000 value='zero' endian='LE' type='Double'                                                                                   3.49 %      Β±13.03% Β±17.33% Β±22.56%
buffers/buffer-read-float.js n=1000000 value='zero' endian='LE' type='Float'                                                                                   -5.15 %      Β±12.46% Β±16.58% Β±21.59%
buffers/buffer-read-with-byteLength.js byteLength=1 n=1000000 type='IntBE' buffer='fast'                                                                        1.94 %      Β±12.21% Β±16.25% Β±21.15%
buffers/buffer-read-with-byteLength.js byteLength=1 n=1000000 type='IntLE' buffer='fast'                                                                        2.38 %      Β±10.75% Β±14.31% Β±18.63%
buffers/buffer-read-with-byteLength.js byteLength=1 n=1000000 type='UIntBE' buffer='fast'                                                                       1.26 %      Β±12.83% Β±17.08% Β±22.22%
buffers/buffer-read-with-byteLength.js byteLength=1 n=1000000 type='UIntLE' buffer='fast'                                                                       0.78 %       Β±9.44% Β±12.56% Β±16.36%
buffers/buffer-read-with-byteLength.js byteLength=2 n=1000000 type='IntBE' buffer='fast'                                                                        0.58 %      Β±15.47% Β±20.58% Β±26.79%
buffers/buffer-read-with-byteLength.js byteLength=2 n=1000000 type='IntLE' buffer='fast'                                                                        8.51 %      Β±15.54% Β±20.67% Β±26.91%
buffers/buffer-read-with-byteLength.js byteLength=2 n=1000000 type='UIntBE' buffer='fast'                                                                      -7.37 %      Β±10.08% Β±13.43% Β±17.51%
buffers/buffer-read-with-byteLength.js byteLength=2 n=1000000 type='UIntLE' buffer='fast'                                                                      -3.82 %      Β±14.12% Β±18.78% Β±24.44%
buffers/buffer-read-with-byteLength.js byteLength=3 n=1000000 type='IntBE' buffer='fast'                                                                        2.12 %      Β±14.21% Β±18.90% Β±24.60%
buffers/buffer-read-with-byteLength.js byteLength=3 n=1000000 type='IntLE' buffer='fast'                                                                **     22.65 %      Β±15.09% Β±20.08% Β±26.14%
buffers/buffer-read-with-byteLength.js byteLength=3 n=1000000 type='UIntBE' buffer='fast'                                                                      -1.84 %      Β±15.32% Β±20.38% Β±26.52%
buffers/buffer-read-with-byteLength.js byteLength=3 n=1000000 type='UIntLE' buffer='fast'                                                                       1.57 %       Β±6.82%  Β±9.07% Β±11.81%
buffers/buffer-read-with-byteLength.js byteLength=4 n=1000000 type='IntBE' buffer='fast'                                                                        7.12 %      Β±15.46% Β±20.57% Β±26.77%
buffers/buffer-read-with-byteLength.js byteLength=4 n=1000000 type='IntLE' buffer='fast'                                                                      -12.22 %      Β±14.25% Β±18.96% Β±24.69%
buffers/buffer-read-with-byteLength.js byteLength=4 n=1000000 type='UIntBE' buffer='fast'                                                                       5.63 %      Β±15.52% Β±20.66% Β±26.89%
buffers/buffer-read-with-byteLength.js byteLength=4 n=1000000 type='UIntLE' buffer='fast'                                                                      -4.44 %      Β±15.08% Β±20.06% Β±26.11%
buffers/buffer-read-with-byteLength.js byteLength=5 n=1000000 type='IntBE' buffer='fast'                                                                       -1.65 %       Β±9.53% Β±12.68% Β±16.51%
buffers/buffer-read-with-byteLength.js byteLength=5 n=1000000 type='IntLE' buffer='fast'                                                                       -0.47 %      Β±10.35% Β±13.77% Β±17.93%
buffers/buffer-read-with-byteLength.js byteLength=5 n=1000000 type='UIntBE' buffer='fast'                                                                      -5.76 %      Β±11.67% Β±15.53% Β±20.21%
buffers/buffer-read-with-byteLength.js byteLength=5 n=1000000 type='UIntLE' buffer='fast'                                                                       3.80 %       Β±9.38% Β±12.50% Β±16.29%
buffers/buffer-read-with-byteLength.js byteLength=6 n=1000000 type='IntBE' buffer='fast'                                                                       -1.41 %       Β±7.21%  Β±9.60% Β±12.50%
buffers/buffer-read-with-byteLength.js byteLength=6 n=1000000 type='IntLE' buffer='fast'                                                                       -0.46 %       Β±7.90% Β±10.51% Β±13.69%
buffers/buffer-read-with-byteLength.js byteLength=6 n=1000000 type='UIntBE' buffer='fast'                                                                       4.10 %       Β±9.28% Β±12.36% Β±16.09%
buffers/buffer-read-with-byteLength.js byteLength=6 n=1000000 type='UIntLE' buffer='fast'                                                                       1.20 %      Β±10.15% Β±13.51% Β±17.58%
buffers/buffer-read.js n=1000000 type='BigInt64BE' buffer='fast'                                                                                         *     -8.01 %       Β±6.77%  Β±9.01% Β±11.73%
buffers/buffer-read.js n=1000000 type='BigInt64LE' buffer='fast'                                                                                               -1.32 %       Β±6.12%  Β±8.15% Β±10.63%
buffers/buffer-read.js n=1000000 type='BigUInt64BE' buffer='fast'                                                                                               7.86 %      Β±20.04% Β±26.66% Β±34.70%
buffers/buffer-read.js n=1000000 type='BigUInt64LE' buffer='fast'                                                                                              -7.50 %      Β±14.80% Β±19.69% Β±25.63%
buffers/buffer-read.js n=1000000 type='Int16BE' buffer='fast'                                                                                                  -4.74 %      Β±17.59% Β±23.41% Β±30.46%
buffers/buffer-read.js n=1000000 type='Int16LE' buffer='fast'                                                                                                 -13.30 %      Β±18.89% Β±25.13% Β±32.70%
buffers/buffer-read.js n=1000000 type='Int32BE' buffer='fast'                                                                                                  -4.74 %      Β±19.42% Β±25.83% Β±33.62%
buffers/buffer-read.js n=1000000 type='Int32LE' buffer='fast'                                                                                                  -7.69 %      Β±16.69% Β±22.20% Β±28.90%
buffers/buffer-read.js n=1000000 type='Int8' buffer='fast'                                                                                                    -13.45 %      Β±19.64% Β±26.13% Β±34.01%
buffers/buffer-read.js n=1000000 type='UInt16BE' buffer='fast'                                                                                                -12.52 %      Β±17.23% Β±22.93% Β±29.84%
buffers/buffer-read.js n=1000000 type='UInt16LE' buffer='fast'                                                                                                 -6.06 %      Β±17.94% Β±23.87% Β±31.06%
buffers/buffer-read.js n=1000000 type='UInt32BE' buffer='fast'                                                                                                 14.02 %      Β±22.28% Β±29.64% Β±38.58%
buffers/buffer-read.js n=1000000 type='UInt32LE' buffer='fast'                                                                                                  3.69 %      Β±21.77% Β±28.97% Β±37.70%
buffers/buffer-read.js n=1000000 type='UInt8' buffer='fast'                                                                                              *    -13.41 %      Β±12.29% Β±16.38% Β±21.40%
buffers/buffer-slice.js n=1000000 type='fast'                                                                                                                  -0.57 %       Β±2.60%  Β±3.47%  Β±4.51%
buffers/buffer-slice.js n=1000000 type='slow'                                                                                                                  -0.64 %       Β±2.99%  Β±3.98%  Β±5.18%
buffers/buffer-slice.js n=1000000 type='subarray'                                                                                                               2.00 %       Β±3.82%  Β±5.09%  Β±6.65%
buffers/buffer-swap.js n=1000000 len=1024 method='swap16' aligned='false'                                                                                      -0.18 %       Β±0.77%  Β±1.03%  Β±1.34%
buffers/buffer-swap.js n=1000000 len=1024 method='swap16' aligned='true'                                                                                       -0.37 %       Β±0.98%  Β±1.31%  Β±1.71%
buffers/buffer-swap.js n=1000000 len=1024 method='swap32' aligned='false'                                                                                       0.04 %       Β±0.68%  Β±0.91%  Β±1.19%
buffers/buffer-swap.js n=1000000 len=1024 method='swap32' aligned='true'                                                                                       -0.23 %       Β±0.55%  Β±0.73%  Β±0.95%
buffers/buffer-swap.js n=1000000 len=1024 method='swap64' aligned='false'                                                                                       0.20 %       Β±0.62%  Β±0.82%  Β±1.07%
buffers/buffer-swap.js n=1000000 len=1024 method='swap64' aligned='true'                                                                                       -0.38 %       Β±0.56%  Β±0.74%  Β±0.96%
buffers/buffer-swap.js n=1000000 len=2056 method='swap16' aligned='false'                                                                                      -0.17 %       Β±0.65%  Β±0.86%  Β±1.12%
buffers/buffer-swap.js n=1000000 len=2056 method='swap16' aligned='true'                                                                                       -0.03 %       Β±0.61%  Β±0.81%  Β±1.05%
buffers/buffer-swap.js n=1000000 len=2056 method='swap32' aligned='false'                                                                                *      0.35 %       Β±0.35%  Β±0.46%  Β±0.60%
buffers/buffer-swap.js n=1000000 len=2056 method='swap32' aligned='true'                                                                                        0.13 %       Β±0.29%  Β±0.39%  Β±0.50%
buffers/buffer-swap.js n=1000000 len=2056 method='swap64' aligned='false'                                                                                      -0.09 %       Β±0.34%  Β±0.46%  Β±0.60%
buffers/buffer-swap.js n=1000000 len=2056 method='swap64' aligned='true'                                                                                        0.17 %       Β±0.34%  Β±0.45%  Β±0.59%
buffers/buffer-swap.js n=1000000 len=256 method='swap16' aligned='false'                                                                                        1.35 %       Β±1.40%  Β±1.86%  Β±2.42%
buffers/buffer-swap.js n=1000000 len=256 method='swap16' aligned='true'                                                                                         1.02 %       Β±1.76%  Β±2.34%  Β±3.05%
buffers/buffer-swap.js n=1000000 len=256 method='swap32' aligned='false'                                                                                       -1.64 %       Β±1.95%  Β±2.60%  Β±3.39%
buffers/buffer-swap.js n=1000000 len=256 method='swap32' aligned='true'                                                                                         0.64 %       Β±1.62%  Β±2.16%  Β±2.82%
buffers/buffer-swap.js n=1000000 len=256 method='swap64' aligned='false'                                                                                       -0.62 %       Β±1.45%  Β±1.93%  Β±2.51%
buffers/buffer-swap.js n=1000000 len=256 method='swap64' aligned='true'                                                                                        -0.94 %       Β±1.87%  Β±2.49%  Β±3.24%
buffers/buffer-swap.js n=1000000 len=64 method='swap16' aligned='false'                                                                                        -0.09 %       Β±0.94%  Β±1.25%  Β±1.62%
buffers/buffer-swap.js n=1000000 len=64 method='swap16' aligned='true'                                                                                          1.51 %       Β±2.12%  Β±2.82%  Β±3.68%
buffers/buffer-swap.js n=1000000 len=64 method='swap32' aligned='false'                                                                                         0.17 %       Β±0.48%  Β±0.64%  Β±0.83%
buffers/buffer-swap.js n=1000000 len=64 method='swap32' aligned='true'                                                                                         -0.14 %       Β±0.57%  Β±0.76%  Β±0.99%
buffers/buffer-swap.js n=1000000 len=64 method='swap64' aligned='false'                                                                                        -0.59 %       Β±0.99%  Β±1.32%  Β±1.72%
buffers/buffer-swap.js n=1000000 len=64 method='swap64' aligned='true'                                                                                         -0.57 %       Β±1.19%  Β±1.58%  Β±2.06%
buffers/buffer-swap.js n=1000000 len=768 method='swap16' aligned='false'                                                                                        0.49 %       Β±0.85%  Β±1.13%  Β±1.47%
buffers/buffer-swap.js n=1000000 len=768 method='swap16' aligned='true'                                                                                         1.14 %       Β±1.19%  Β±1.58%  Β±2.07%
buffers/buffer-swap.js n=1000000 len=768 method='swap32' aligned='false'                                                                                        0.87 %       Β±1.02%  Β±1.36%  Β±1.77%
buffers/buffer-swap.js n=1000000 len=768 method='swap32' aligned='true'                                                                                         0.12 %       Β±1.01%  Β±1.35%  Β±1.76%
buffers/buffer-swap.js n=1000000 len=768 method='swap64' aligned='false'                                                                                        0.35 %       Β±0.68%  Β±0.90%  Β±1.18%
buffers/buffer-swap.js n=1000000 len=768 method='swap64' aligned='true'                                                                                         0.10 %       Β±0.72%  Β±0.95%  Β±1.24%
buffers/buffer-swap.js n=1000000 len=8192 method='swap16' aligned='false'                                                                                       0.13 %       Β±0.15%  Β±0.20%  Β±0.26%
buffers/buffer-swap.js n=1000000 len=8192 method='swap16' aligned='true'                                                                                        0.09 %       Β±0.15%  Β±0.20%  Β±0.26%
buffers/buffer-swap.js n=1000000 len=8192 method='swap32' aligned='false'                                                                                       0.08 %       Β±0.08%  Β±0.11%  Β±0.14%
buffers/buffer-swap.js n=1000000 len=8192 method='swap32' aligned='true'                                                                                       -0.01 %       Β±0.07%  Β±0.09%  Β±0.12%
buffers/buffer-swap.js n=1000000 len=8192 method='swap64' aligned='false'                                                                                      -0.04 %       Β±0.10%  Β±0.13%  Β±0.17%
buffers/buffer-swap.js n=1000000 len=8192 method='swap64' aligned='true'                                                                                       -0.02 %       Β±0.10%  Β±0.13%  Β±0.17%
buffers/buffer-tojson.js len=0 n=10000                                                                                                                         -3.37 %      Β±18.74% Β±24.93% Β±32.45%
buffers/buffer-tojson.js len=256 n=10000                                                                                                                       -0.92 %       Β±1.76%  Β±2.34%  Β±3.05%
buffers/buffer-tojson.js len=4096 n=10000                                                                                                                       1.57 %       Β±1.65%  Β±2.19%  Β±2.86%
buffers/buffer-tostring.js n=1000000 len=1 args=0 encoding=''                                                                                                  -2.46 %       Β±2.61%  Β±3.48%  Β±4.53%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='ascii'                                                                                             -0.89 %       Β±2.57%  Β±3.43%  Β±4.46%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='hex'                                                                                                0.40 %       Β±2.40%  Β±3.19%  Β±4.15%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='latin1'                                                                                            -0.89 %       Β±4.04%  Β±5.38%  Β±7.02%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='UCS-2'                                                                                              0.87 %       Β±2.14%  Β±2.84%  Β±3.70%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='utf8'                                                                                               2.43 %       Β±3.01%  Β±4.00%  Β±5.21%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='ascii'                                                                                             -0.06 %       Β±3.26%  Β±4.33%  Β±5.64%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='hex'                                                                                                0.51 %       Β±1.88%  Β±2.50%  Β±3.26%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='latin1'                                                                                             0.91 %       Β±2.92%  Β±3.89%  Β±5.07%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='UCS-2'                                                                                             -0.28 %       Β±1.49%  Β±1.99%  Β±2.59%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='utf8'                                                                                               0.10 %       Β±3.34%  Β±4.44%  Β±5.78%
buffers/buffer-tostring.js n=1000000 len=1024 args=0 encoding=''                                                                                               -0.44 %       Β±1.18%  Β±1.58%  Β±2.05%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='ascii'                                                                                           0.19 %       Β±1.18%  Β±1.57%  Β±2.05%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='hex'                                                                                             0.53 %       Β±0.66%  Β±0.88%  Β±1.15%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='latin1'                                                                                         -0.72 %       Β±1.57%  Β±2.09%  Β±2.72%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='UCS-2'                                                                                           0.54 %       Β±0.94%  Β±1.25%  Β±1.63%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='utf8'                                                                                     *      1.64 %       Β±1.37%  Β±1.82%  Β±2.37%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='ascii'                                                                                           1.20 %       Β±1.38%  Β±1.83%  Β±2.39%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='hex'                                                                                             0.21 %       Β±0.56%  Β±0.75%  Β±0.98%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='latin1'                                                                                         -0.67 %       Β±1.28%  Β±1.70%  Β±2.22%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='UCS-2'                                                                                          -0.69 %       Β±0.88%  Β±1.17%  Β±1.52%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='utf8'                                                                                            0.75 %       Β±1.38%  Β±1.83%  Β±2.39%
buffers/buffer-tostring.js n=1000000 len=64 args=0 encoding=''                                                                                                  0.64 %       Β±1.76%  Β±2.34%  Β±3.05%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='ascii'                                                                                            -0.29 %       Β±1.49%  Β±1.98%  Β±2.59%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='hex'                                                                                               1.19 %       Β±2.12%  Β±2.82%  Β±3.67%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='latin1'                                                                                            0.75 %       Β±2.18%  Β±2.89%  Β±3.77%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='UCS-2'                                                                                            -0.06 %       Β±1.30%  Β±1.74%  Β±2.26%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='utf8'                                                                                             -1.67 %       Β±3.59%  Β±4.81%  Β±6.35%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='ascii'                                                                                             0.64 %       Β±1.74%  Β±2.32%  Β±3.02%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='hex'                                                                                              -2.00 %       Β±2.31%  Β±3.07%  Β±4.00%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='latin1'                                                                                           -0.70 %       Β±2.06%  Β±2.75%  Β±3.58%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='UCS-2'                                                                                             0.38 %       Β±1.90%  Β±2.53%  Β±3.31%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='utf8'                                                                                              1.27 %       Β±1.67%  Β±2.22%  Β±2.89%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='ascii' fromEncoding='ascii'                                                                          -0.17 %       Β±1.73%  Β±2.30%  Β±2.99%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='ascii' fromEncoding='latin1'                                                                         -0.12 %       Β±1.67%  Β±2.22%  Β±2.90%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='ascii' fromEncoding='ucs2'                                                                           -0.87 %       Β±2.23%  Β±2.96%  Β±3.86%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='ascii' fromEncoding='utf8'                                                                            0.65 %       Β±1.86%  Β±2.47%  Β±3.22%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='latin1' fromEncoding='ascii'                                                                         -0.30 %       Β±1.47%  Β±1.96%  Β±2.55%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='latin1' fromEncoding='latin1'                                                                         0.40 %       Β±1.18%  Β±1.57%  Β±2.05%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='latin1' fromEncoding='ucs2'                                                                           0.47 %       Β±1.83%  Β±2.44%  Β±3.17%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='latin1' fromEncoding='utf8'                                                                          -0.43 %       Β±1.70%  Β±2.26%  Β±2.96%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='ucs2' fromEncoding='ascii'                                                                           -1.43 %       Β±1.92%  Β±2.55%  Β±3.33%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='ucs2' fromEncoding='latin1'                                                                           0.62 %       Β±2.07%  Β±2.75%  Β±3.58%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='ucs2' fromEncoding='ucs2'                                                                            -0.48 %       Β±1.67%  Β±2.22%  Β±2.90%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='ucs2' fromEncoding='utf8'                                                                            -1.15 %       Β±1.93%  Β±2.57%  Β±3.35%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='utf8' fromEncoding='ascii'                                                                           -0.08 %       Β±1.43%  Β±1.90%  Β±2.47%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='utf8' fromEncoding='latin1'                                                                          -0.39 %       Β±1.42%  Β±1.89%  Β±2.46%
buffers/buffer-transcode.js n=100000 length=1 toEncoding='utf8' fromEncoding='utf8'                                                                             0.17 %       Β±1.50%  Β±1.99%  Β±2.59%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='ascii' fromEncoding='ascii'                                                                          0.97 %       Β±1.80%  Β±2.40%  Β±3.12%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='ascii' fromEncoding='latin1'                                                                         0.56 %       Β±1.73%  Β±2.30%  Β±3.00%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='ascii' fromEncoding='ucs2'                                                                           0.85 %       Β±1.42%  Β±1.89%  Β±2.46%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='ascii' fromEncoding='utf8'                                                                          -0.70 %       Β±1.95%  Β±2.59%  Β±3.37%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='latin1' fromEncoding='ascii'                                                                        -0.60 %       Β±1.64%  Β±2.19%  Β±2.85%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='latin1' fromEncoding='latin1'                                                                       -0.91 %       Β±1.53%  Β±2.03%  Β±2.65%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='latin1' fromEncoding='ucs2'                                                                          1.30 %       Β±1.82%  Β±2.42%  Β±3.15%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='latin1' fromEncoding='utf8'                                                                         -0.13 %       Β±1.85%  Β±2.46%  Β±3.20%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='ucs2' fromEncoding='ascii'                                                                   **      2.59 %       Β±1.69%  Β±2.25%  Β±2.93%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='ucs2' fromEncoding='latin1'                                                                         -0.55 %       Β±1.63%  Β±2.17%  Β±2.83%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='ucs2' fromEncoding='ucs2'                                                                    **      2.05 %       Β±1.53%  Β±2.04%  Β±2.66%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='ucs2' fromEncoding='utf8'                                                                            1.26 %       Β±1.69%  Β±2.25%  Β±2.94%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='utf8' fromEncoding='ascii'                                                                           1.05 %       Β±2.11%  Β±2.80%  Β±3.65%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='utf8' fromEncoding='latin1'                                                                   *     -1.60 %       Β±1.58%  Β±2.10%  Β±2.73%
buffers/buffer-transcode.js n=100000 length=10 toEncoding='utf8' fromEncoding='utf8'                                                                     *     -1.89 %       Β±1.75%  Β±2.33%  Β±3.03%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='ascii' fromEncoding='ascii'                                                                       -0.93 %       Β±1.16%  Β±1.54%  Β±2.00%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='ascii' fromEncoding='latin1'                                                                       0.38 %       Β±1.21%  Β±1.61%  Β±2.09%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='ascii' fromEncoding='ucs2'                                                                        -0.02 %       Β±0.22%  Β±0.30%  Β±0.39%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='ascii' fromEncoding='utf8'                                                                        -1.32 %       Β±1.38%  Β±1.84%  Β±2.39%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='latin1' fromEncoding='ascii'                                                                       0.08 %       Β±0.94%  Β±1.25%  Β±1.63%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='latin1' fromEncoding='latin1'                                                                     -0.24 %       Β±0.85%  Β±1.13%  Β±1.47%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='latin1' fromEncoding='ucs2'                                                                       -0.15 %       Β±0.24%  Β±0.33%  Β±0.42%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='latin1' fromEncoding='utf8'                                                                       -0.84 %       Β±0.87%  Β±1.16%  Β±1.52%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='ucs2' fromEncoding='ascii'                                                                         0.54 %       Β±1.04%  Β±1.38%  Β±1.80%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='ucs2' fromEncoding='latin1'                                                                        0.27 %       Β±1.02%  Β±1.35%  Β±1.76%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='ucs2' fromEncoding='ucs2'                                                                         -0.08 %       Β±0.68%  Β±0.90%  Β±1.17%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='ucs2' fromEncoding='utf8'                                                                         -0.05 %       Β±1.00%  Β±1.33%  Β±1.73%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='utf8' fromEncoding='ascii'                                                                         0.05 %       Β±0.72%  Β±0.96%  Β±1.25%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='utf8' fromEncoding='latin1'                                                                       -0.15 %       Β±0.80%  Β±1.06%  Β±1.39%
buffers/buffer-transcode.js n=100000 length=1000 toEncoding='utf8' fromEncoding='utf8'                                                                          0.01 %       Β±0.80%  Β±1.07%  Β±1.39%
buffers/buffer-write-string-short.js n=1000000 len=1 encoding='ascii'                                                                                          -0.18 %       Β±2.78%  Β±3.70%  Β±4.82%
buffers/buffer-write-string-short.js n=1000000 len=1 encoding='latin1'                                                                                          0.84 %       Β±3.55%  Β±4.73%  Β±6.17%
buffers/buffer-write-string-short.js n=1000000 len=1 encoding='utf8'                                                                                           -0.39 %       Β±3.56%  Β±4.74%  Β±6.17%
buffers/buffer-write-string-short.js n=1000000 len=16 encoding='ascii'                                                                                          1.37 %       Β±3.10%  Β±4.13%  Β±5.38%
buffers/buffer-write-string-short.js n=1000000 len=16 encoding='latin1'                                                                                  *     -3.83 %       Β±3.64%  Β±4.84%  Β±6.31%
buffers/buffer-write-string-short.js n=1000000 len=16 encoding='utf8'                                                                                           0.96 %       Β±3.94%  Β±5.25%  Β±6.86%
buffers/buffer-write-string-short.js n=1000000 len=32 encoding='ascii'                                                                                         -0.43 %       Β±2.51%  Β±3.34%  Β±4.35%
buffers/buffer-write-string-short.js n=1000000 len=32 encoding='latin1'                                                                                         1.58 %       Β±3.93%  Β±5.23%  Β±6.82%
buffers/buffer-write-string-short.js n=1000000 len=32 encoding='utf8'                                                                                          -1.31 %       Β±3.94%  Β±5.24%  Β±6.83%
buffers/buffer-write-string-short.js n=1000000 len=8 encoding='ascii'                                                                                          -0.92 %       Β±3.97%  Β±5.28%  Β±6.88%
buffers/buffer-write-string-short.js n=1000000 len=8 encoding='latin1'                                                                                          1.63 %       Β±4.12%  Β±5.48%  Β±7.13%
buffers/buffer-write-string-short.js n=1000000 len=8 encoding='utf8'                                                                                           -1.75 %       Β±3.29%  Β±4.37%  Β±5.69%
buffers/buffer-write-string.js n=1000000 len=2048 args='' encoding=''                                                                                          -0.01 %       Β±0.28%  Β±0.37%  Β±0.48%
buffers/buffer-write-string.js n=1000000 len=2048 args='' encoding='ascii'                                                                             ***     -2.90 %       Β±1.58%  Β±2.12%  Β±2.77%
buffers/buffer-write-string.js n=1000000 len=2048 args='' encoding='hex'                                                                                        0.45 %       Β±0.68%  Β±0.91%  Β±1.18%
buffers/buffer-write-string.js n=1000000 len=2048 args='' encoding='latin1'                                                                                    -0.24 %       Β±1.40%  Β±1.86%  Β±2.42%
buffers/buffer-write-string.js n=1000000 len=2048 args='' encoding='utf16le'                                                                                    0.55 %       Β±1.22%  Β±1.63%  Β±2.12%
buffers/buffer-write-string.js n=1000000 len=2048 args='' encoding='utf8'                                                                               **      0.75 %       Β±0.54%  Β±0.72%  Β±0.94%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset' encoding=''                                                                                     0.65 %       Β±1.03%  Β±1.37%  Β±1.79%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset' encoding='ascii'                                                                                2.36 %       Β±3.67%  Β±4.88%  Β±6.35%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset' encoding='hex'                                                                         ***     -1.48 %       Β±0.85%  Β±1.13%  Β±1.48%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset' encoding='latin1'                                                                               0.56 %       Β±3.34%  Β±4.44%  Β±5.78%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset' encoding='utf16le'                                                                      **      3.11 %       Β±2.14%  Β±2.84%  Β±3.70%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset' encoding='utf8'                                                                         **      2.24 %       Β±1.57%  Β±2.09%  Β±2.72%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset+length' encoding=''                                                                              0.62 %       Β±0.94%  Β±1.25%  Β±1.64%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset+length' encoding='ascii'                                                                         0.11 %       Β±2.80%  Β±3.73%  Β±4.86%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset+length' encoding='hex'                                                                          -0.31 %       Β±0.54%  Β±0.72%  Β±0.94%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset+length' encoding='latin1'                                                               ***      8.24 %       Β±3.35%  Β±4.46%  Β±5.81%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset+length' encoding='utf16le'                                                                      -0.35 %       Β±1.94%  Β±2.60%  Β±3.39%
buffers/buffer-write-string.js n=1000000 len=2048 args='offset+length' encoding='utf8'                                                                          0.97 %       Β±1.11%  Β±1.48%  Β±1.93%
buffers/buffer-write.js n=1000000 type='BigInt64BE' buffer='fast'                                                                                               0.35 %       Β±1.94%  Β±2.58%  Β±3.36%
buffers/buffer-write.js n=1000000 type='BigInt64LE' buffer='fast'                                                                                              -1.34 %       Β±1.98%  Β±2.63%  Β±3.43%
buffers/buffer-write.js n=1000000 type='BigUInt64BE' buffer='fast'                                                                                      **     -2.64 %       Β±1.66%  Β±2.21%  Β±2.89%
buffers/buffer-write.js n=1000000 type='BigUInt64LE' buffer='fast'                                                                                              1.65 %       Β±1.72%  Β±2.29%  Β±2.98%
buffers/buffer-write.js n=1000000 type='DoubleBE' buffer='fast'                                                                                                 2.25 %      Β±14.95% Β±19.89% Β±25.89%
buffers/buffer-write.js n=1000000 type='DoubleLE' buffer='fast'                                                                                                 1.41 %      Β±14.99% Β±19.95% Β±25.96%
buffers/buffer-write.js n=1000000 type='FloatBE' buffer='fast'                                                                                                  1.01 %      Β±16.07% Β±21.38% Β±27.83%
buffers/buffer-write.js n=1000000 type='FloatLE' buffer='fast'                                                                                                 -8.07 %      Β±15.13% Β±20.13% Β±26.20%
buffers/buffer-write.js n=1000000 type='Int16BE' buffer='fast'                                                                                                 -6.06 %      Β±13.96% Β±18.58% Β±24.18%
buffers/buffer-write.js n=1000000 type='Int16LE' buffer='fast'                                                                                                 -2.89 %      Β±14.23% Β±18.93% Β±24.64%
buffers/buffer-write.js n=1000000 type='Int32BE' buffer='fast'                                                                                                 -9.14 %      Β±15.02% Β±20.01% Β±26.08%
buffers/buffer-write.js n=1000000 type='Int32LE' buffer='fast'                                                                                                  9.94 %      Β±18.60% Β±24.76% Β±32.23%
buffers/buffer-write.js n=1000000 type='Int8' buffer='fast'                                                                                                    -3.43 %      Β±12.10% Β±16.11% Β±20.96%
buffers/buffer-write.js n=1000000 type='IntBE' buffer='fast'                                                                                                   -5.34 %       Β±9.07% Β±12.07% Β±15.71%
buffers/buffer-write.js n=1000000 type='IntLE' buffer='fast'                                                                                                    7.27 %      Β±10.16% Β±13.52% Β±17.60%
buffers/buffer-write.js n=1000000 type='UInt16BE' buffer='fast'                                                                                                -2.96 %      Β±13.91% Β±18.51% Β±24.09%
buffers/buffer-write.js n=1000000 type='UInt16LE' buffer='fast'                                                                                          *     19.15 %      Β±16.02% Β±21.34% Β±27.82%
buffers/buffer-write.js n=1000000 type='UInt32BE' buffer='fast'                                                                                                 7.51 %       Β±9.55% Β±12.71% Β±16.54%
buffers/buffer-write.js n=1000000 type='UInt32LE' buffer='fast'                                                                                                 4.99 %      Β±11.06% Β±14.72% Β±19.16%
buffers/buffer-write.js n=1000000 type='UInt8' buffer='fast'                                                                                                    0.04 %      Β±14.91% Β±19.84% Β±25.82%
buffers/buffer-write.js n=1000000 type='UIntBE' buffer='fast'                                                                                                   2.04 %      Β±13.56% Β±18.04% Β±23.48%
buffers/buffer-write.js n=1000000 type='UIntLE' buffer='fast'                                                                                                  -1.58 %      Β±11.92% Β±15.86% Β±20.64%
buffers/buffer-zero.js type='buffer' n=1000000                                                                                                                 -1.00 %       Β±2.07%  Β±2.76%  Β±3.59%
buffers/buffer-zero.js type='string' n=1000000                                                                                                           *      4.44 %       Β±3.80%  Β±5.08%  Β±6.65%
buffers/dataview-set.js n=1000000 type='Float32BE'                                                                                                              0.44 %       Β±6.80%  Β±9.05% Β±11.78%
buffers/dataview-set.js n=1000000 type='Float32LE'                                                                                                             -0.97 %       Β±5.11%  Β±6.80%  Β±8.86%
buffers/dataview-set.js n=1000000 type='Float64BE'                                                                                                             -1.46 %       Β±7.21%  Β±9.60% Β±12.49%
buffers/dataview-set.js n=1000000 type='Float64LE'                                                                                                              0.31 %       Β±5.99%  Β±7.97% Β±10.38%
buffers/dataview-set.js n=1000000 type='Int16BE'                                                                                                                0.78 %       Β±3.22%  Β±4.29%  Β±5.59%
buffers/dataview-set.js n=1000000 type='Int16LE'                                                                                                                0.13 %       Β±4.58%  Β±6.09%  Β±7.93%
buffers/dataview-set.js n=1000000 type='Int32BE'                                                                                                                1.32 %       Β±3.89%  Β±5.18%  Β±6.75%
buffers/dataview-set.js n=1000000 type='Int32LE'                                                                                                                0.37 %       Β±2.74%  Β±3.65%  Β±4.75%
buffers/dataview-set.js n=1000000 type='Int8'                                                                                                            *     -2.28 %       Β±2.12%  Β±2.83%  Β±3.69%
buffers/dataview-set.js n=1000000 type='Uint16BE'                                                                                                               1.02 %       Β±3.25%  Β±4.32%  Β±5.62%
buffers/dataview-set.js n=1000000 type='Uint16LE'                                                                                                              -3.22 %       Β±4.22%  Β±5.62%  Β±7.32%
buffers/dataview-set.js n=1000000 type='Uint32BE'                                                                                                              -1.53 %       Β±1.99%  Β±2.66%  Β±3.48%
buffers/dataview-set.js n=1000000 type='Uint32LE'                                                                                                              -3.02 %       Β±3.13%  Β±4.17%  Β±5.44%
buffers/dataview-set.js n=1000000 type='Uint8'                                                                                                                  0.61 %       Β±1.77%  Β±2.35%  Β±3.06%

@ChALkeR
Copy link
Member

ChALkeR commented Feb 28, 2026

Let's hold off until we figure out what's going on

@ronag Which benchmark is that in the PR description?

If it's not in tree, could you add it (or modify buffer-copy.js) to test behavior on:

  • Buffer.alloc(x, 1)
  • Buffer.from(new ArrayBuffer(x)).fill(1)
  • Buffer.allocUnsafeSlow(x).fill(1)
  • Buffer.from(new SharedArrayBuffer(x)).fill(1)

All of those are important / could give different results

This should be tested with benchmarks code

Also the bech should have 64/128 bytes in sizes (along others lower/higher) as there is a sharp difference there in how the data is stored in some cases.

@ChALkeR
Copy link
Member

ChALkeR commented Feb 28, 2026

Also i'm curious why is v8 slower on SAB there
Are we sure that our _copy impl does not lack some logic around that / works correctly on SAB?

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

Also i'm curious why is v8 slower on SAB there

Because the javascript memory model is super strict.

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

ChatGPT:

So on ARM, set() on SAB can differ from memcpy in at least three concrete ways:
It may devolve into a byte/element loop (because the spec describes it that way, and SAB semantics restrict bulk optimizations).
It may avoid wide vector stores to prevent tearing / weird observability under races (especially for β€œno-tear” configurations).
It may do an extra clone if the views overlap in the same underlying (shared) data block.

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

So from what I understand on ARM the implementation is not allowed to use SIMD since it invalidated the "no-tear" requirement of the memory model, while on x86 this is not a problem.

I think we maybe should document that Buffer.copy (and in general all buffer operations that we implement) do not strictly follow the ecmascript memory model guarantees. @mcollina

@Renegade334
Copy link
Member

Also i'm curious why is v8 slower on SAB there
Are we sure that our _copy impl does not lack some logic around that / works correctly on SAB?

AFAIA it's that V8 uses a libatomic-based memmove implementation if the source or target is SAB-backed.

@ChALkeR
Copy link
Member

ChALkeR commented Mar 1, 2026

Huh, we likely have another bug in _copy

Details Doc: https://nodejs.org/api/buffer.html#bufcopytarget-targetstart-sourcestart-sourceend > Copies data from a region of buf to a region in target, even if the target memory region overlaps with buf.

It should be using memove, not memcpy then

Those are different under some libs/optimizations

E.g.:

I have not verified that the issue exists yet, but given the overall lack of bound checks in _copy it needs a recheck

Upd: No, _copy uses memmove, not memcpy.

It may do an extra clone if the views overlap in the same underlying (shared) data block.

This is hallucinated, _copy doesn't use memcpy.

@ChALkeR
Copy link
Member

ChALkeR commented Mar 1, 2026

I think we maybe should document that Buffer.copy (and in general all buffer operations that we implement) do not strictly follow the ecmascript memory model guarantees

How often are Buffer.from(SAB) used and where?
The question is do we want to drop that guarantee for the sake of the perf for those usecases, or is it a bug

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

I think we maybe should document that Buffer.copy (and in general all buffer operations that we implement) do not strictly follow the ecmascript memory model guarantees

How often are Buffer.from(SAB) used and where? The question is do we want to drop that guarantee for the sake of the perf for those usecases, or is it a bug

When it's used it's super important. It's the only way to efficiently use workers in node. Also implementing that guarantee needs us to update most buffer operations which will make things harder to maintain, e.g. rewriting Buffer.write to adhere to the strict memory model is not a trivial task. IMHO it's better to have the current more relaxed memory model for node buffers and document it.

and TBH it doesn't make any difference for this PR since sometimes the implementation uses set and sometimes _copy which make the whole situation even more confusing.

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

This is hallucinated, _copy doesn't use memcpy.

It's talking about typedarray.set, not _copy.

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

@ChALkeR I do see you have good intentions here and you are probably right. But this is becoming to much work for what I feel is a rather straightforward change. We run x86 in production which is not affected by this so I can't motivate spending much more time on this.

Please feel free to take over this PR or open a different one. I'm happy to continue discussing but getting this over the finish line seems like a too big task for me at the moment.

IMHO I would recommend to land this is as revert of a change causing a perf regression and then start over with 2 different PR's in regards to the memory model and the performance (set is faster in certain scenarios) topics.

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

I think @jasnell might have some insightful opinions in regards to the difference between memory models of Buffer and TypedArray, i.e. Buffer is much more relaxed (context is in regards to SharedArrayBuffer as the backing store).

@ChALkeR
Copy link
Member

ChALkeR commented Mar 1, 2026

It's talking about typedarray.set, not _copy.

Yes, it's talking about typedarray.set vs memcpy, and the bottom part of that is not relevant as this is PR is really typedarray.set vs _copy which is memmove (not memcpy), so memcpy overlapping concerns (the cited part) do not apply to this PR. So that's not the answer.

causing a perf regression

Perf regression under which usecase?

But this is becoming to much work for what I feel is a rather straightforward change.

Also it's not demonstrated.
Perf regression from landing this is demonstrated in benchmarks though, in .copy over regular common Buffers.

@ChALkeR
Copy link
Member

ChALkeR commented Mar 1, 2026

Perf regression under which usecase?

If this is about Buffer.from(new SharedArrayBuffer, there is only a single lib over 10k downloads/month that appears to have that literal string:

157837	@pnpm:tarball-fetcher-1003.0.0.tgz/lib/remoteTarballFetcher.js:130:                data = Buffer.from(new SharedArrayBuffer(downloaded));

There might be more non-literal matches, but this hints at low usage anyway.

What exactly is affected that justifies regressing .copy perf for everything else?

note: this perf question is orthogonal to the concern that using _copy on SAB might give wrong results, that is smth we should check separately from this PR as this is not the PR that introduces that, it might be wrong in main

Copy link
Member

@ChALkeR ChALkeR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should land perf-only PRs without benchmarks that demonstrate the improvement

So far, existing benchmarks demonstrate only slowdown

Even if this is landed (in the current form), it is likely to be flipped back in another attempt to optimize under the guidance of maintained benchmarks

Separately, when benchmarks are introduced, we should consider if that's a usecase that is likely to happen / under what conditions (and if that is worth a slowdown on other common usecases). I don't say that this doesn't have usage, but so far it's unclear from the current PR.

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

import { bench, run, group, summary } from 'mitata'

const SIZES = [64, 256, 1024, 4096, 16_384, 65_536, 256_000, 1024_000]

for (const size of SIZES) {
  const src = Buffer.alloc(size, 0x42)

  const abDst = Buffer.from(new ArrayBuffer(size))
  const sabDst = Buffer.from(new SharedArrayBuffer(size))

  summary(() => {
    group(`Buffer.copy ${size} bytes`, () => {
      bench(`ArrayBuffer (${size})`, () => {
        src.copy(abDst)
      })

      bench(`SharedArrayBuffer (${size})`, () => {
        src.copy(sabDst)
      })
    })
  })
}
await run()
clk: ~3.68 GHz
cpu: Apple M3 Pro
runtime: node 25.6.1 (arm64-darwin)

Size      ArrayBuffer    SharedArrayBuffer    Slowdown    AB IPC    SAB IPC
──────    ───────────    ─────────────────    ────────    ──────    ───────
64 B       10.65 ns           12.47 ns        1.17x      7.40       6.60
256 B      12.43 ns           20.72 ns        1.67x      7.00       5.86
1 KiB      19.76 ns           51.77 ns        2.62x      6.50       4.80
4 KiB      57.98 ns          163.05 ns        2.81x      4.95       4.79
16 KiB    235.94 ns          602.94 ns        2.56x      3.95       4.88
64 KiB    645.66 ns            2.31 Β΅s        3.58x      5.39       4.93
256 KiB     3.30 Β΅s            8.96 Β΅s        2.72x      4.05       4.93
1 MiB      13.13 Β΅s           37.43 Β΅s        2.85x      4.06       4.91

@ronag ronag closed this Mar 1, 2026
@ronag ronag reopened this Mar 1, 2026
@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

@RafaelGSS maybe you can assists with measuring + benchmarks on this to possibly unblock the PR?

@ChALkeR
Copy link
Member

ChALkeR commented Mar 1, 2026

Thanks for the benchmark!

I think it was a mistake to compare only relative SAB/AB perf, not absolute with/without patch.
(This is also why benchmarks matter to support performance claims)

According to that bench (modified to not use a dep), comparing 24.11.0 to 24.12.0 (which introduced that change in the first place), I expect that this PR is a slowdown for both SAB and ArrayBuffer on sizes <= 256 (or slightly larger)

It makes AB and SAB values approximately equal there, so the coef is brought to ~1x, but it just makes them equally slow.

For sizes 1k-16k, according to that provided benchmark, this significantly slows down regular Buffer but significantly improves SAB.

For sizes >=65k this has almost no effect on regular Buffer but significantly improves SAB.

This hints at a better fix - not plain revert (that makes AB worse and even SAB worse on small buffers), not SAB detection, but a mix of SAB + size detection.

24.12.0 (with #60399):

ArrayBuffer (64) x 55,944,332 ops/sec @ 17ns/op (0ns..62ΞΌs)
SharedArrayBuffer (64) x 54,226,486 ops/sec @ 18ns/op (0ns..40ΞΌs)

ArrayBuffer (256) x 53,484,271 ops/sec @ 18ns/op (0ns..50ΞΌs)
SharedArrayBuffer (256) x 43,170,692 ops/sec @ 23ns/op (0ns..45ΞΌs)

ArrayBuffer (1024) x 39,508,050 ops/sec @ 25ns/op (0ns..81ΞΌs)
SharedArrayBuffer (1024) x 18,266,498 ops/sec @ 54ns/op (0ns..598ΞΌs)

ArrayBuffer (4096) x 16,610,492 ops/sec @ 60ns/op (0ns..167ΞΌs)
SharedArrayBuffer (4096) x 6,111,767 ops/sec @ 163ns/op (83ns..284ΞΌs)

ArrayBuffer (16384) x 4,518,893 ops/sec @ 221ns/op (83ns..33ΞΌs)
SharedArrayBuffer (16384) x 1,724,397 ops/sec @ 579ns/op (458ns..3ms)

ArrayBuffer (65536) x 1,072,019 ops/sec @ 932ns/op (666ns..1062ΞΌs)
SharedArrayBuffer (65536) x 450,827 ops/sec @ 2ΞΌs/op (2ΞΌs..138ΞΌs)

ArrayBuffer (256000) x 266,026 ops/sec @ 3ΞΌs/op (3ΞΌs..79ΞΌs)
SharedArrayBuffer (256000) x 115,247 ops/sec @ 8ΞΌs/op (8ΞΌs..162ΞΌs)

ArrayBuffer (1024000) x 66,486 ops/sec @ 15ΞΌs/op (14ΞΌs..284ΞΌs)
SharedArrayBuffer (1024000) x 29,303 ops/sec @ 34ΞΌs/op (33ΞΌs..122ΞΌs)

24.11.0 (likely where with this revert would bring us):

ArrayBuffer (64) x 35,945,832 ops/sec @ 27ns/op (0ns..66ΞΌs)
SharedArrayBuffer (64) x 35,986,388 ops/sec @ 27ns/op (0ns..105ΞΌs)

ArrayBuffer (256) x 31,984,815 ops/sec @ 31ns/op (0ns..83ΞΌs)
SharedArrayBuffer (256) x 31,965,087 ops/sec @ 31ns/op (0ns..49ΞΌs)

ArrayBuffer (1024) x 25,381,144 ops/sec @ 39ns/op (0ns..33ΞΌs)
SharedArrayBuffer (1024) x 25,602,860 ops/sec @ 39ns/op (0ns..46ΞΌs)

ArrayBuffer (4096) x 13,687,190 ops/sec @ 73ns/op (0ns..41ΞΌs)
SharedArrayBuffer (4096) x 13,724,997 ops/sec @ 72ns/op (0ns..36ΞΌs)

ArrayBuffer (16384) x 4,195,405 ops/sec @ 238ns/op (125ns..54ΞΌs)
SharedArrayBuffer (16384) x 4,176,256 ops/sec @ 239ns/op (84ns..35ΞΌs)

ArrayBuffer (65536) x 1,100,011 ops/sec @ 909ns/op (625ns..47ΞΌs)
SharedArrayBuffer (65536) x 1,058,282 ops/sec @ 944ns/op (708ns..25ΞΌs)

ArrayBuffer (256000) x 267,497 ops/sec @ 3ΞΌs/op (3ΞΌs..55ΞΌs)
SharedArrayBuffer (256000) x 267,308 ops/sec @ 3ΞΌs/op (3ΞΌs..37ΞΌs)

ArrayBuffer (1024000) x 66,538 ops/sec @ 15ΞΌs/op (14ΞΌs..147ΞΌs)
SharedArrayBuffer (1024000) x 66,529 ops/sec @ 15ΞΌs/op (14ΞΌs..94ΞΌs)

That said, I have not tested applying this to main yet.

Copy link
Member

@ChALkeR ChALkeR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I re-tested this PR and compared it to base branch without it

In short: this PR description mentions sizes 256 and 4096 with relative "slowdown" on SAB compared to AB, and claims to improve that relative slowdown.

What is does instead is makes both AB and SAB slower on size=256. Down to an identical value though.

It has benefits for on higher lengths though, for Buffer.from(new SharedArrayBuffer( only.

But it also still hurts regular Buffer instances up to ~16k, and Buffer.from(new SharedArrayBuffer( is very rare to justify noticeable slowdown on regular Buffer.

This needs not just benchmarks, but the implementation fixed to not cause a perf regression.

Base
ArrayBuffer (64) x 54,529,149 ops/sec @ 18ns/op (0ns..305ΞΌs)
SharedArrayBuffer (64) x 53,716,573 ops/sec @ 18ns/op (0ns..38ΞΌs)

ArrayBuffer (256) x 52,328,394 ops/sec @ 19ns/op (0ns..41ΞΌs)
SharedArrayBuffer (256) x 41,411,669 ops/sec @ 24ns/op (0ns..42ΞΌs)

ArrayBuffer (1024) x 38,529,150 ops/sec @ 25ns/op (0ns..36ΞΌs)
SharedArrayBuffer (1024) x 18,232,579 ops/sec @ 54ns/op (0ns..41ΞΌs)

ArrayBuffer (4096) x 16,600,224 ops/sec @ 60ns/op (0ns..40ΞΌs)
SharedArrayBuffer (4096) x 6,146,755 ops/sec @ 162ns/op (42ns..59ΞΌs)

ArrayBuffer (16384) x 3,042,573 ops/sec @ 328ns/op (83ns..72ΞΌs)
SharedArrayBuffer (16384) x 1,741,612 ops/sec @ 574ns/op (458ns..45ΞΌs)

ArrayBuffer (65536) x 1,053,112 ops/sec @ 949ns/op (666ns..70ΞΌs)
SharedArrayBuffer (65536) x 451,151 ops/sec @ 2ΞΌs/op (2ΞΌs..60ΞΌs)

ArrayBuffer (256000) x 251,257 ops/sec @ 3ΞΌs/op (3ΞΌs..10ms)
SharedArrayBuffer (256000) x 116,322 ops/sec @ 8ΞΌs/op (8ΞΌs..80ΞΌs)

ArrayBuffer (1024000) x 66,171 ops/sec @ 15ΞΌs/op (14ΞΌs..206ΞΌs)
SharedArrayBuffer (1024000) x 29,225 ops/sec @ 34ΞΌs/op (33ΞΌs..135ΞΌs)
This PR
ArrayBuffer (64) x 40,335,525 ops/sec @ 24ns/op (0ns..46ΞΌs)
SharedArrayBuffer (64) x 39,725,116 ops/sec @ 25ns/op (0ns..80ΞΌs)

ArrayBuffer (256) x 35,785,083 ops/sec @ 27ns/op (0ns..45ΞΌs)
SharedArrayBuffer (256) x 35,819,652 ops/sec @ 27ns/op (0ns..39ΞΌs)

ArrayBuffer (1024) x 27,800,955 ops/sec @ 35ns/op (0ns..41ΞΌs)
SharedArrayBuffer (1024) x 27,316,682 ops/sec @ 36ns/op (0ns..57ΞΌs)

ArrayBuffer (4096) x 14,335,737 ops/sec @ 69ns/op (0ns..35ΞΌs)
SharedArrayBuffer (4096) x 14,335,732 ops/sec @ 69ns/op (0ns..84ΞΌs)

ArrayBuffer (16384) x 3,025,528 ops/sec @ 330ns/op (84ns..43ΞΌs)
SharedArrayBuffer (16384) x 2,995,333 ops/sec @ 333ns/op (125ns..36ΞΌs)

ArrayBuffer (65536) x 1,053,536 ops/sec @ 949ns/op (708ns..23ΞΌs)
SharedArrayBuffer (65536) x 1,052,752 ops/sec @ 949ns/op (708ns..67ΞΌs)

ArrayBuffer (256000) x 265,626 ops/sec @ 3ΞΌs/op (3ΞΌs..62ΞΌs)
SharedArrayBuffer (256000) x 266,723 ops/sec @ 3ΞΌs/op (3ΞΌs..55ΞΌs)

ArrayBuffer (1024000) x 66,146 ops/sec @ 15ΞΌs/op (14ΞΌs..170ΞΌs)
SharedArrayBuffer (1024000) x 66,000 ops/sec @ 15ΞΌs/op (14ΞΌs..102ΞΌs)

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

but the implementation fixed to not cause a perf regression.

If someone wants to do that go ahead. I still think this PR is better than the current state of things, i.e. both have acceptable performance while the current state of things is AB with great performance and SAB with horrible performance. If you look at the numbers the AB regression you mention is 6ns (?) while the SAB regression I want to fix is 1000+ ns (?).

Also we should document that difference in the memory model for Buffer vs TypedArray, if no-one else feels comfortable doing that I will try to make time for that at some point.

@ronag
Copy link
Member Author

ronag commented Mar 1, 2026

Digging into Relaxed_Memcpy I don't see how it would be different from a normal memcpy on any mainstream architecture. Possibly this is simply not an optimized path where strict spec conformance is prioritized.

@ChALkeR
Copy link
Member

ChALkeR commented Mar 1, 2026

cc @nodejs/v8

@ChALkeR
Copy link
Member

ChALkeR commented Mar 2, 2026

the AB regression you mention is 6ns (?) while the SAB regression I want to fix is 1000+ ns (?).

First, not only AB regression but both AB and SAB regression here up for length at least up to 256

Second, you seem to be comparing Buffer.alloc(64) to Buffer.from(new SharedArrayBuffer(64 * 1024)) for those 6ns vs 1000ns numbers? The relative perf is what matters more here, not absolute difference across sizes that are 3 orders of magnitude apart. Small copies are more frequent and can accumulate to higher values.

Third, see the usecase concern. This trades 1.0x-1.4x (depending on size) perf on copying Buffer.alloc() / Buffer.from() for 0.7x - 2.3x (depending on size) perf on copying Buffer.from(new SharedArrayBuffer()).
Given the relative frequency of both, I predict that landing this will result in much more cpu-hours wasted than won in total.

This PR does demonstrate that there is smth with SAB going on on higher lengths, but it needs someone to fix this and should not land as-is.

I.e. agree on "If someone wants to do that go ahead" and this is likely fixable into an actual improvement, disagree on "I still think this PR is better than the current state of things", for making vastly most common case significantly worse and the usecase concern.

@ronag ronag closed this Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. buffer Issues and PRs related to the buffer subsystem. needs-benchmark-ci PR that need a benchmark CI run. needs-ci PRs that need a full CI run. performance Issues and PRs related to the performance of Node.js.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants