Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions benchmark/buffers/buffer-of.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

const common = require('../common.js');

// Measure Buffer.of(...items) throughput for various lengths.
// We prebuild the items array to avoid measuring array construction,
// and vary the effective iterations with length to keep total work reasonable.

const bench = common.createBenchmark(main, {
len: [0, 1, 8, 64, 256, 1024],
n: [5e5],
});

function main({ len, n }) {
const items = new Array(len);
for (let i = 0; i < len; i++) items[i] = i & 0xFF;

bench.start();
for (let i = 0; i < n; i++) {
Buffer.of(...items);
}
bench.end(n);
}
41 changes: 37 additions & 4 deletions doc/api/buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -827,8 +827,9 @@ A `TypeError` will be thrown if `size` is not a number.
The `Buffer` module pre-allocates an internal `Buffer` instance of
size [`Buffer.poolSize`][] that is used as a pool for the fast allocation of new
`Buffer` instances created using [`Buffer.allocUnsafe()`][], [`Buffer.from(array)`][],
[`Buffer.from(string)`][], and [`Buffer.concat()`][] only when `size` is less than
`Buffer.poolSize >>> 1` (floor of [`Buffer.poolSize`][] divided by two).
[`Buffer.from(string)`][], [`Buffer.of(...items)`][], and [`Buffer.concat()`][]
only when `size` is less than `Buffer.poolSize >>> 1` (floor of [`Buffer.poolSize`][]
divided by two).

Use of this pre-allocated internal memory pool is a key difference between
calling `Buffer.alloc(size, fill)` vs. `Buffer.allocUnsafe(size).fill(fill)`.
Expand Down Expand Up @@ -1419,6 +1420,36 @@ appropriate for `Buffer.from()` variants.
[`Buffer.from(string)`][] may also use the internal `Buffer` pool like
[`Buffer.allocUnsafe()`][] does.

### Static method: `Buffer.of(...items)`

<!-- YAML
added: v5.10.0
-->

* `...items` {integer} A sequence of numeric byte values (0–255).
* Returns: {Buffer}

Creates a new `Buffer` from the given numeric arguments.

This is equivalent to the standard `TypedArray.of()` factory, but returns a
`Buffer` instead of a generic `Uint8Array`. Each argument provides the value of
the corresponding byte in the resulting buffer.

```mjs
import { Buffer } from 'node:buffer';

const buf = Buffer.of(0x62, 0x75, 0x66, 0x66, 0x65, 0x72);
```

```cjs
const { Buffer } = require('node:buffer');

const buf = Buffer.of(0x62, 0x75, 0x66, 0x66, 0x65, 0x72);
```

[`Buffer.of(...items)`][] may also use the internal `Buffer` pool like
[`Buffer.allocUnsafe()`][] does.

### Static method: `Buffer.isBuffer(obj)`

<!-- YAML
Expand Down Expand Up @@ -5461,8 +5492,9 @@ to one of these new APIs._
potentially sensitive.

`Buffer` instances returned by [`Buffer.allocUnsafe()`][], [`Buffer.from(string)`][],
[`Buffer.concat()`][] and [`Buffer.from(array)`][] _may_ be allocated off a shared
internal memory pool if `size` is less than or equal to half [`Buffer.poolSize`][].
[`Buffer.of(...items)`][], [`Buffer.concat()`][], and [`Buffer.from(array)`][]
_may_ be allocated off a shared internal memory pool if `size` is less than or
equal to half [`Buffer.poolSize`][].
Instances returned by [`Buffer.allocUnsafeSlow()`][] _never_ use the shared internal
memory pool.

Expand Down Expand Up @@ -5515,6 +5547,7 @@ introducing security vulnerabilities into an application.
[`Buffer.from(arrayBuf)`]: #static-method-bufferfromarraybuffer-byteoffset-length
[`Buffer.from(buffer)`]: #static-method-bufferfrombuffer
[`Buffer.from(string)`]: #static-method-bufferfromstring-encoding
[`Buffer.of(...items)`]: #static-method-bufferofitems
[`Buffer.poolSize`]: #bufferpoolsize
[`ERR_INVALID_BUFFER_SIZE`]: errors.md#err_invalid_buffer_size
[`ERR_OUT_OF_RANGE`]: errors.md#err_out_of_range
Expand Down
4 changes: 2 additions & 2 deletions doc/api/webstreams.md
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ available.

Do not pass a pooled {Buffer} object instance in to this method.
Pooled `Buffer` objects are created using `Buffer.allocUnsafe()`,
or `Buffer.from()`, or are often returned by various `node:fs` module
callbacks. These types of `Buffer`s use a shared underlying
`Buffer.from()`, or `Buffer.of()` are often returned by various `node:fs`
module callbacks. These types of `Buffer`s use a shared underlying
{ArrayBuffer} object that contains all of the data from all of
the pooled `Buffer` instances. When a `Buffer`, {TypedArray},
or {DataView} is passed in to `readableStreamBYOBReader.read()`,
Expand Down
25 changes: 19 additions & 6 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,17 +375,30 @@ Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) {
TypedArrayPrototypeGetByteLength(view)));
};

// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated
// Buffer() constructor. Must use arrow function syntax to avoid automatically
// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated Buffer()
// constructor and may use the buffer pool. Must use arrow function syntax to avoid automatically
// adding a `prototype` property and making the function a constructor.
//
// Refs: https://tc39.github.io/ecma262/#sec-%typedarray%.of
// Refs: https://esdiscuss.org/topic/isconstructor#content-11
const of = (...items) => {
const newObj = createUnsafeBuffer(items.length);
for (let k = 0; k < items.length; k++)
newObj[k] = items[k];
return newObj;
const len = items.length;
if (len === 0) return new FastBuffer();
if (len < (Buffer.poolSize >>> 1)) {
if (len > (poolSize - poolOffset))
createPool();
const b = new FastBuffer(allocPool, poolOffset, len);
for (let k = 0; k < len; k++)
b[k] = items[k];
poolOffset += len;
alignPool();
return b;
}

const b = createUnsafeBuffer(len);
for (let k = 0; k < len; k++)
b[k] = items[k];
return b;
};
Buffer.of = of;

Expand Down
Loading