Skip to content

src: use stack allocation for small string encoding#62431

Merged
nodejs-github-bot merged 2 commits intonodejs:mainfrom
thisalihassan:src-string-bytes-stack-encode
Apr 9, 2026
Merged

src: use stack allocation for small string encoding#62431
nodejs-github-bot merged 2 commits intonodejs:mainfrom
thisalihassan:src-string-bytes-stack-encode

Conversation

@thisalihassan
Copy link
Copy Markdown
Contributor

  • Introduce EncodeOneByteString / EncodeTwoByteString helper templates in StringBytes::Encode() that use a 512 byte (256-char for two-byte) stack buffer for small inputs, falling back to heap allocation + ExternString for larger ones.
  • Covers all encoding paths: ASCII, HEX, BASE64, BASE64URL, UTF8 (two-byte), and UCS2.

Refs: nodejs/performance#194

                                                                       confidence improvement accuracy (*)   (**)  (***)
buffers/buffer-base64-encode.js n=32 len=67108864                                      1.82 %       ±2.53% ±3.38% ±4.42%
buffers/buffer-base64url-encode.js n=32 len=67108864                            *     -1.70 %       ±1.39% ±1.86% ±2.42%
buffers/buffer-tostring.js n=1000000 len=1 args=0 encoding=''                 ***      3.71 %       ±1.67% ±2.23% ±2.91%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='ascii'                     0.21 %       ±2.08% ±2.78% ±3.65%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='hex'              ***     40.34 %       ±4.17% ±5.60% ±7.39%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='latin1'           ***      2.52 %       ±1.15% ±1.53% ±1.99%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='UCS-2'            ***      3.33 %       ±1.26% ±1.68% ±2.19%
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='utf8'             ***      2.03 %       ±0.90% ±1.19% ±1.55%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='ascii'              *      3.00 %       ±2.83% ±3.80% ±5.02%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='hex'              ***     40.40 %       ±3.23% ±4.30% ±5.59%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='latin1'            **      2.93 %       ±2.04% ±2.73% ±3.58%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='UCS-2'            ***      4.55 %       ±1.17% ±1.56% ±2.04%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='utf8'             ***      2.52 %       ±0.88% ±1.17% ±1.52%
buffers/buffer-tostring.js n=1000000 len=1024 args=0 encoding=''                      -0.48 %       ±1.75% ±2.35% ±3.09%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='ascii'                  2.68 %       ±3.68% ±4.91% ±6.44%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='hex'                   -0.05 %       ±1.47% ±1.96% ±2.55%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='latin1'          *      2.53 %       ±1.94% ±2.60% ±3.41%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='UCS-2'                  0.75 %       ±1.80% ±2.40% ±3.13%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='utf8'            *      3.19 %       ±2.47% ±3.33% ±4.40%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='ascii'                  0.01 %       ±2.15% ±2.86% ±3.72%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='hex'                    0.40 %       ±1.31% ±1.74% ±2.26%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='latin1'          *      1.96 %       ±1.86% ±2.48% ±3.23%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='UCS-2'                  0.54 %       ±1.99% ±2.65% ±3.46%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='utf8'                   1.05 %       ±1.11% ±1.48% ±1.93%
buffers/buffer-tostring.js n=1000000 len=64 args=0 encoding=''                        -0.37 %       ±1.28% ±1.72% ±2.26%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='ascii'                   -1.33 %       ±2.21% ±2.97% ±3.92%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='hex'             ***     41.64 %       ±2.07% ±2.76% ±3.62%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='latin1'            *      1.98 %       ±1.86% ±2.48% ±3.25%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='UCS-2'                   -0.38 %       ±2.76% ±3.68% ±4.80%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='utf8'                     0.64 %       ±0.88% ±1.18% ±1.53%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='ascii'                    0.35 %       ±2.91% ±3.88% ±5.07%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='hex'             ***     40.54 %       ±1.43% ±1.90% ±2.48%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='latin1'                   1.67 %       ±2.47% ±3.30% ±4.31%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='UCS-2'                    0.32 %       ±1.93% ±2.57% ±3.35%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='utf8'                     0.56 %       ±0.91% ±1.21% ±1.58%

Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case, there are 35 comparisons, you can thus
expect the following amount of false-positive results:
  1.75 false positives, when considering a   5% risk acceptance (*, **, ***),
  0.35 false positives, when considering a   1% risk acceptance (**, ***),
  0.04 false positives, when considering a 0.1% risk acceptance (***)
thisalihassan@Alis-MacBook-Pro node % 

@nodejs-github-bot nodejs-github-bot added buffer Issues and PRs related to the buffer subsystem. c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. labels Mar 25, 2026
@thisalihassan thisalihassan force-pushed the src-string-bytes-stack-encode branch from e5fbafb to 43fd2f8 Compare March 25, 2026 11:05
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 25, 2026

Codecov Report

❌ Patch coverage is 87.50000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.80%. Comparing base (f48ac91) to head (f38c303).
⚠️ Report is 18 commits behind head on main.

Files with missing lines Patch % Lines
src/string_bytes.cc 87.50% 0 Missing and 6 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62431      +/-   ##
==========================================
+ Coverage   89.77%   89.80%   +0.02%     
==========================================
  Files         697      697              
  Lines      215749   215755       +6     
  Branches    41304    41285      -19     
==========================================
+ Hits       193681   193751      +70     
+ Misses      14161    14123      -38     
+ Partials     7907     7881      -26     
Files with missing lines Coverage Δ
src/string_bytes.cc 74.63% <87.50%> (+4.96%) ⬆️

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

@thisalihassan thisalihassan force-pushed the src-string-bytes-stack-encode branch from 43fd2f8 to 73eb342 Compare March 27, 2026 12:26
@ronag ronag added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Mar 29, 2026
@ronag ronag added the request-ci Add this label to start a Jenkins CI on a PR. label Mar 29, 2026
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Mar 29, 2026
@nodejs-github-bot

This comment was marked as outdated.

@thisalihassan

This comment was marked as outdated.

@ronag ronag added the request-ci Add this label to start a Jenkins CI on a PR. label Mar 31, 2026
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Mar 31, 2026
@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

Use stack-allocated buffers in StringBytes::Encode() for small inputs
instead of heap-allocating via UncheckedMalloc for every call.

Refs: nodejs/performance#194
@thisalihassan thisalihassan force-pushed the src-string-bytes-stack-encode branch from fd449b1 to f38c303 Compare April 7, 2026 11:08
@Flarna Flarna added the request-ci Add this label to start a Jenkins CI on a PR. label Apr 8, 2026
@thisalihassan

This comment was marked as outdated.

@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 8, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@Flarna Flarna 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 Apr 9, 2026
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Apr 9, 2026
@nodejs-github-bot nodejs-github-bot merged commit 70c1d6b into nodejs:main Apr 9, 2026
75 of 78 checks passed
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Landed in 70c1d6b

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. c++ Issues and PRs that require attention from people who are familiar with C++. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants