Skip to content

Conversation

@gurgunday
Copy link
Member

@gurgunday gurgunday commented Oct 25, 2025

Huge win by avoiding complex _copyActual logic when we can copy the whole source into target. The native copy implementation is faster only for partial copies.

Before:

buffers/buffer-concat-fill.js
buffers/buffer-concat-fill.js n=800000 extraSize=1: 3,080,309.438799309
buffers/buffer-concat-fill.js n=800000 extraSize=256: 2,718,494.3906977526
buffers/buffer-concat-fill.js n=800000 extraSize=1024: 2,592,930.9112553936

buffers/buffer-concat.js
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=4: 6,895,296.007515873
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=4: 6,850,915.824861098
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=4: 6,714,498.121438699
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=4: 6,606,244.795672606
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=4: 3,875,370.506613865
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=4: 4,427,107.007979794
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=16: 2,202,621.1880456866
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=16: 2,308,511.109946339
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=16: 2,111,185.355049204
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=16: 2,169,882.104202485
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=16: 993,752.7633158871
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=16: 1,010,066.0454915363

After:

buffers/buffer-concat-fill.js
buffers/buffer-concat-fill.js n=800000 extraSize=1: 4,213,313.932988885
buffers/buffer-concat-fill.js n=800000 extraSize=256: 3,999,625.0351529545
buffers/buffer-concat-fill.js n=800000 extraSize=1024: 3,271,098.409944823

buffers/buffer-concat.js
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=4: 12,018,365.504695036
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=4: 11,561,090.427597769
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=4: 11,106,682.475733392
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=4: 10,827,423.883277772
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=4: 6,297,132.164792359
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=4: 6,326,826.005617953
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=16: 4,151,263.382265607
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=16: 4,295,939.1963506
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=16: 3,758,688.301977228
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=16: 3,904,910.547041359
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=16: 1,265,188.4389452678
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=16: 1,284,207.4931866652

@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 Oct 25, 2025
@gurgunday gurgunday added the performance Issues and PRs related to the performance of Node.js. label Oct 25, 2025
@codecov
Copy link

codecov bot commented Oct 25, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.56%. Comparing base (2bda7cb) to head (a8a5e19).
⚠️ Report is 59 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #60399      +/-   ##
==========================================
- Coverage   88.56%   88.56%   -0.01%     
==========================================
  Files         704      704              
  Lines      207774   207832      +58     
  Branches    40025    40048      +23     
==========================================
+ Hits       184022   184066      +44     
+ Misses      15807    15806       -1     
- Partials     7945     7960      +15     
Files with missing lines Coverage Δ
lib/buffer.js 100.00% <100.00%> (ø)

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

@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

@aduh95
Copy link
Contributor

aduh95 commented Oct 25, 2025

Benchmark GHA: https://github.com/aduh95/node/actions/runs/18809427089
Benchmark CI: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/1746/

Results (improvements across the board)
336.392                                                                              confidence improvement accuracy (*)   (**)  (***)
336.392  buffers/buffer-concat-fill.js n=800000 extraSize=1                                 ***     18.19 %       ±1.07% ±1.42% ±1.85%
336.392  buffers/buffer-concat-fill.js n=800000 extraSize=1024                              ***     12.89 %       ±0.87% ±1.16% ±1.51%
336.392  buffers/buffer-concat-fill.js n=800000 extraSize=256                               ***     16.73 %       ±0.87% ±1.16% ±1.51%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=16          ***    100.26 %       ±1.68% ±2.26% ±2.99%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=4           ***     56.72 %       ±2.03% ±2.72% ±3.60%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=16         ***     96.79 %       ±1.62% ±2.17% ±2.87%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=4          ***     60.41 %       ±2.24% ±3.00% ±3.93%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=16        ***     12.61 %       ±0.53% ±0.71% ±0.93%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=4         ***     23.27 %       ±1.02% ±1.36% ±1.77%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=16          ***     98.73 %       ±1.27% ±1.71% ±2.26%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=4           ***     57.20 %       ±2.52% ±3.36% ±4.41%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=16         ***     96.40 %       ±1.37% ±1.85% ±2.44%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=4          ***     57.44 %       ±2.48% ±3.32% ±4.36%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=16        ***     11.19 %       ±0.61% ±0.81% ±1.07%
336.392  buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=4         ***     21.48 %       ±1.03% ±1.38% ±1.80%
                                                                            confidence improvement accuracy (*)    (**)   (***)
buffers/buffer-concat-fill.js n=800000 extraSize=1                                 ***     82.25 %      ±16.94% ±22.34% ±28.67%
buffers/buffer-concat-fill.js n=800000 extraSize=1024                              ***     49.50 %      ±11.42% ±15.05% ±19.31%
buffers/buffer-concat-fill.js n=800000 extraSize=256                               ***     71.99 %      ±15.96% ±21.05% ±27.01%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=16          ***    230.61 %      ±19.95% ±26.30% ±33.75%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=1 pieces=4           ***    182.24 %      ±18.07% ±23.82% ±30.57%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=16         ***    218.33 %      ±19.78% ±26.07% ±33.45%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=16 pieces=4          ***    171.75 %      ±18.22% ±24.02% ±30.83%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=16        ***     52.84 %      ±20.58% ±27.13% ±34.82%
buffers/buffer-concat.js n=800000 withTotalLength=0 pieceSize=256 pieces=4         ***     87.04 %      ±17.05% ±22.47% ±28.84%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=16          ***    234.11 %      ±20.43% ±26.94% ±34.57%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=1 pieces=4           ***    174.42 %      ±18.13% ±23.89% ±30.66%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=16         ***    220.85 %      ±20.02% ±26.39% ±33.87%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=16 pieces=4          ***    166.60 %      ±17.70% ±23.33% ±29.94%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=16        ***     52.35 %      ±20.66% ±27.24% ±34.96%
buffers/buffer-concat.js n=800000 withTotalLength=1 pieceSize=256 pieces=4         ***     87.00 %      ±17.03% ±22.46% ±28.82%

Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case, there are 15 comparisons, you can thus
expect the following amount of false-positive results:
  0.75 false positives, when considering a   5% risk acceptance (*, **, ***),
  0.15 false positives, when considering a   1% risk acceptance (**, ***),
  0.01 false positives, when considering a 0.1% risk acceptance (***)

@gurgunday
Copy link
Member Author

@aduh95 the CI didn't pick up the benchmarks, I think the category is buffers instead of buffer

This reverts commit 34adb7c.
ChALkeR

This comment was marked as resolved.

@ChALkeR

This comment was marked as resolved.

@gurgunday
Copy link
Member Author

gurgunday commented Oct 26, 2025

No, they claimed an improvement for copy, which works with TypedArrays.

However, .concat, which only works with UInt8 arrays, did get slower because of this. Because it's now using a more complex logic as well while not needing it.

source = new Uint8Array(source.buffer, source.byteOffset + sourceStart, nb);

Funnily enough, we weren't using primordials here before, but anyway, that change is already made

@ChALkeR

This comment was marked as resolved.

@ChALkeR

This comment was marked as resolved.

Co-authored-by: Nikita Skovoroda <chalkerx@gmail.com>
@gurgunday
Copy link
Member Author

We might need a CI run to verify

@ChALkeR

This comment was marked as off-topic.

@ChALkeR

This comment was marked as resolved.

@gurgunday gurgunday requested a review from mcollina October 28, 2025 22:04
@richardlau
Copy link
Member

The AIX and LinuxOne CI failures look like real issues with this PR and is most likely due to not handling endianness properly.

@ChALkeR

This comment was marked as resolved.

@gurgunday
Copy link
Member Author

Yeah my fault it's the test, will fix it later today

@gurgunday gurgunday removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Oct 29, 2025
@gurgunday
Copy link
Member Author

gurgunday commented Oct 29, 2025

@richardlau thanks, should be fixed

@aduh95 PTAL, it's ready for review again

@gurgunday
Copy link
Member Author

@lpinca PTAL

Ignore the mountain of comments, here are the results, it's non-breaking

You can run the bench again but it's ready with a request-ci

@RafaelGSS RafaelGSS added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Oct 31, 2025
@aduh95 aduh95 added commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Oct 31, 2025
@nodejs-github-bot nodejs-github-bot added commit-queue-failed An error occurred while landing this pull request using GitHub Actions. and removed commit-queue Add this label to land a pull request using GitHub Actions. labels Oct 31, 2025
@nodejs-github-bot
Copy link
Collaborator

Commit Queue failed
- Loading data for nodejs/node/pull/60399
✔  Done loading data for nodejs/node/pull/60399
----------------------------------- PR info ------------------------------------
Title      buffer: speed up concat via TypedArray#set (#60399)
   ⚠  Could not retrieve the email or name of the PR author's from user's GitHub profile!
Branch     gurgunday:buffer-concat -> nodejs:main
Labels     buffer, performance, author ready, needs-ci, commit-queue-squash
Commits    10
 - buffer: speed up concat via TypedArray#set
 - complete coverage
 - store bufLength in a variable
 - fix compat issue
 - lint
 - simplify
 - Revert "simplify"
 - alternative implementation
 - add type check to set
 - fix test
Committers 1
 - Gürgün Dayıoğlu <hey@gurgun.day>
PR-URL: https://github.com/nodejs/node/pull/60399
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
------------------------------ Generated metadata ------------------------------
PR-URL: https://github.com/nodejs/node/pull/60399
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
--------------------------------------------------------------------------------
   ℹ  This PR was created on Sat, 25 Oct 2025 00:47:41 GMT
   ✔  Approvals: 3
   ✔  - Matteo Collina (@mcollina) (TSC): https://github.com/nodejs/node/pull/60399#pullrequestreview-3380174635
   ✔  - Antoine du Hamel (@aduh95) (TSC): https://github.com/nodejs/node/pull/60399#pullrequestreview-3380355020
   ✔  - Rafael Gonzaga (@RafaelGSS) (TSC): https://github.com/nodejs/node/pull/60399#pullrequestreview-3405890961
   ✔  Last GitHub CI successful
   ℹ  Last Benchmark CI on 2025-10-27T22:47:38Z: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/1748/
   ℹ  Last Full PR CI on 2025-10-27T23:11:11Z: https://ci.nodejs.org/job/node-test-pull-request/69912/
   ⚠  Commits were pushed after the last Full PR CI run:
   ⚠  - fix test
- Querying data for job/node-test-pull-request/69912/
   ✔  Last Jenkins CI successful
--------------------------------------------------------------------------------
   ✔  Aborted `git node land` session in /home/runner/work/node/node/.ncu
https://github.com/nodejs/node/actions/runs/18983880877

@gurgunday
Copy link
Member Author

@aduh95 it needs a CI run after the test fix

@RafaelGSS RafaelGSS added request-ci Add this label to start a Jenkins CI on a PR. and removed commit-queue-failed An error occurred while landing this pull request using GitHub Actions. labels Oct 31, 2025
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Oct 31, 2025
@nodejs-github-bot
Copy link
Collaborator

@aduh95 aduh95 added the commit-queue Add this label to land a pull request using GitHub Actions. label Nov 1, 2025
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Nov 1, 2025
@nodejs-github-bot nodejs-github-bot merged commit 24bebd0 into nodejs:main Nov 1, 2025
82 checks passed
@nodejs-github-bot
Copy link
Collaborator

Landed in 24bebd0

@gurgunday gurgunday deleted the buffer-concat branch November 1, 2025 22:58
aduh95 pushed a commit that referenced this pull request Nov 5, 2025
PR-URL: #60399
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
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. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. 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.

7 participants