Skip to content

buffer: optimize Buffer.toString('hex') for small buffers with stack allocation #194

@thisalihassan

Description

@thisalihassan

While looking into buffer optimizations (nodejs/node#61871), I noticed that Buffer.toString('hex') heap allocates a temporary buffer for every call even for tiny inputs like a SHA-256 digest

I tried using a 512 byte stack buffer for small inputs (<=256 bytes / 512 hex chars) and calling NewFromOneByte directly, skipping ExternOneByteString entirely. This covers all the common cases SHA-256, SHA-512, UUIDs, HMAC signatures, MongoDB ObjectIds, etc.

Let me know what you guys think of this (runs=60)

                                                                    confidence improvement accuracy (*)   (**)  (***)
buffers/buffer-tostring.js n=1000000 len=1 args=1 encoding='hex'           ***     34.44 %       ±1.05% ±1.39% ±1.80%
buffers/buffer-tostring.js n=1000000 len=1 args=3 encoding='hex'           ***     32.38 %       ±2.10% ±2.79% ±3.61%
buffers/buffer-tostring.js n=1000000 len=1024 args=1 encoding='hex'        ***     -1.11 %       ±0.62% ±0.82% ±1.07%
buffers/buffer-tostring.js n=1000000 len=1024 args=3 encoding='hex'                -0.84 %       ±0.88% ±1.17% ±1.51%
buffers/buffer-tostring.js n=1000000 len=128 args=1 encoding='hex'         ***     29.00 %       ±1.67% ±2.22% ±2.88%
buffers/buffer-tostring.js n=1000000 len=128 args=3 encoding='hex'         ***     30.72 %       ±0.79% ±1.05% ±1.35%
buffers/buffer-tostring.js n=1000000 len=256 args=1 encoding='hex'         ***     26.65 %       ±0.93% ±1.23% ±1.59%
buffers/buffer-tostring.js n=1000000 len=256 args=3 encoding='hex'         ***     27.13 %       ±1.46% ±1.93% ±2.49%
buffers/buffer-tostring.js n=1000000 len=512 args=1 encoding='hex'          **     -1.24 %       ±0.85% ±1.12% ±1.44%
buffers/buffer-tostring.js n=1000000 len=512 args=3 encoding='hex'          **     -0.63 %       ±0.41% ±0.55% ±0.71%
buffers/buffer-tostring.js n=1000000 len=64 args=1 encoding='hex'          ***     37.50 %       ±1.65% ±2.18% ±2.81%
buffers/buffer-tostring.js n=1000000 len=64 args=3 encoding='hex'          ***     39.28 %       ±1.29% ±1.72% ±2.23%

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions